@khanacademy/perseus 19.1.9 → 19.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -278,7 +278,7 @@ class MathInput extends React__namespace.Component {
278
278
  className = className + " " + this.props.className;
279
279
  }
280
280
  return /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
281
- style: [styles$B.outerWrapper, this.state.focused && styles$B.wrapperFocused, this.props.hasError && styles$B.wrapperError]
281
+ style: [styles$C.outerWrapper, this.state.focused && styles$C.wrapperFocused, this.props.hasError && styles$C.wrapperError]
282
282
  }, /*#__PURE__*/React__namespace.createElement("div", {
283
283
  style: {
284
284
  display: "flex",
@@ -309,7 +309,7 @@ class MathInput extends React__namespace.Component {
309
309
  dismissEnabled: true,
310
310
  content: () => /*#__PURE__*/React__namespace.createElement(wonderBlocksPopover.PopoverContentCore, {
311
311
  closeButtonVisible: true,
312
- style: styles$B.popoverContent
312
+ style: styles$C.popoverContent
313
313
  }, /*#__PURE__*/React__namespace.createElement(mathInput.DesktopKeypad, _extends({
314
314
  onAnalyticsEvent: this.props.analytics.onAnalyticsEvent,
315
315
  extraKeys: this.props.extraKeys,
@@ -349,9 +349,9 @@ const MathInputIcon = _ref => {
349
349
  color = Color__default["default"].offBlack;
350
350
  break;
351
351
  }
352
- const dynamicClass = active || focused ? styles$B.iconActive : styles$B.iconInactive;
352
+ const dynamicClass = active || focused ? styles$C.iconActive : styles$C.iconInactive;
353
353
  return /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
354
- style: [styles$B.iconContainer, dynamicClass]
354
+ style: [styles$C.iconContainer, dynamicClass]
355
355
  }, /*#__PURE__*/React__namespace.createElement("svg", {
356
356
  xmlns: "http://www.w3.org/2000/svg",
357
357
  width: "16",
@@ -396,7 +396,7 @@ const inputFocused = {
396
396
  borderColor: Color__default["default"].blue,
397
397
  margin: -1
398
398
  };
399
- const styles$B = aphrodite.StyleSheet.create({
399
+ const styles$C = aphrodite.StyleSheet.create({
400
400
  iconContainer: {
401
401
  display: "flex",
402
402
  justifyContent: "center",
@@ -10212,89 +10212,45 @@ const GraphUtils = {
10212
10212
  }
10213
10213
  })($__default["default"], window, document);
10214
10214
 
10215
- /**
10216
- * A work-in-progress of _ methods for objects.
10217
- * That is, they take an object as a parameter,
10218
- * and return an object instead of an array.
10219
- *
10220
- * TODO(aria): Move this out of interactive2
10221
- */
10222
-
10223
- /**
10224
- * Does a pluck on keys inside objects in an object
10225
- *
10226
- * Ex:
10227
- * tools = {
10228
- * translation: {
10229
- * enabled: true
10230
- * },
10231
- * rotation: {
10232
- * enabled: false
10233
- * }
10234
- * };
10235
- * pluckObject(tools, "enabled") returns {
10236
- * translation: true
10237
- * rotation: false
10238
- * }
10239
- */
10240
- const pluck = function (table, subKey) {
10241
- return ___default["default"].object(___default["default"].map(table, function (value, key) {
10242
- return [key, value[subKey]];
10243
- }));
10244
- };
10245
-
10246
- /**
10247
- * Maps an object to an object
10248
- *
10249
- * > mapObject({a: '1', b: '2'}, (value, key) => {
10250
- * return value + 1;
10251
- * });
10252
- * {a: 2, b: 3}
10253
- */
10254
- const mapObject$2 = function (obj, lambda) {
10255
- const result = {};
10256
- ___default["default"].each(___default["default"].keys(obj), function (key) {
10257
- // @ts-expect-error - TS2345 - Argument of type 'string' is not assignable to parameter of type 'K'.
10258
- result[key] = lambda(obj[key], key);
10259
- });
10260
- return result;
10261
- };
10215
+ // Given `coord` and `angle`, find the point where a line extended
10216
+ // from `coord` in the direction of `angle` would be clipped by the
10217
+ // edge of the graphie canvas.
10218
+ const getClipPoint = function (graph, coord, angle) {
10219
+ // Actually put the arrowheads 4px from the edge so they have
10220
+ // a bit of room
10221
+ const xExtent = graph.range[0][1] - graph.range[0][0];
10222
+ const yExtent = graph.range[1][1] - graph.range[1][0];
10262
10223
 
10263
- /**
10264
- * Maps an array to an object
10265
- *
10266
- * > mapObjectFromArray(['a', 'b'], function(elem) {
10267
- * return elem + elem;
10268
- * });
10269
- * {a: 'aa', b: 'bb'}
10270
- */
10271
- const mapObjectFromArray$1 = function (arr, lambda) {
10272
- const result = {};
10273
- ___default["default"].each(arr, function (elem) {
10274
- result[elem] = lambda(elem);
10275
- });
10276
- return result;
10277
- };
10278
- var objective_ = {
10279
- pluck: pluck,
10280
- mapObject: mapObject$2,
10281
- mapObjectFromArray: mapObjectFromArray$1
10224
+ // shoot a point off into the distance ...
10225
+ const distance = xExtent + yExtent;
10226
+ // we need to scale the point according to the scale of the axes
10227
+ const angleVec = graph.unscaleVector(kmath.vector.cartFromPolarDeg(1, angle));
10228
+ const distVec = kmath.vector.scale(kmath.vector.normalize(angleVec), distance);
10229
+ const farCoord = kmath.vector.add(coord, distVec);
10230
+ const scaledAngle = kmath.vector.polarDegFromCart(angleVec)[1];
10231
+ // ... and then bring it back
10232
+ const clipPoint = graph.constrainToBoundsOnAngle(farCoord, 4, scaledAngle * Math.PI / 180);
10233
+ return clipPoint;
10282
10234
  };
10283
10235
 
10284
10236
  /* eslint-disable @babel/no-invalid-this */
10285
10237
 
10286
10238
  /*
10287
- * These functions, when called on the wrapped object, simply pass the
10239
+ * attr() and animate() simply pass the
10288
10240
  * arguments to the underlying Raphael object.
10289
10241
  */
10290
- const PASS_TO_RAPHAEL = ["attr", "animate"];
10291
- const WrappedDefaults = ___default["default"].extend({
10292
- transform: function (transformation) {
10242
+
10243
+ class WrappedDrawing {
10244
+ constructor(graphie, initialPoint) {
10245
+ this.graphie = graphie;
10246
+ this.initialPoint = initialPoint;
10247
+ }
10248
+ transform(transformation) {
10293
10249
  const prefixedTransform = InteractiveUtil.getPrefixedTransform();
10294
10250
  // @ts-expect-error - TS2538 - Type 'null' cannot be used as an index type. | TS2538 - Type 'undefined' cannot be used as an index type.
10295
10251
  this.wrapper.style[prefixedTransform] = transformation;
10296
- },
10297
- toFront: function () {
10252
+ }
10253
+ toFront() {
10298
10254
  const parentNode = this.wrapper.parentNode;
10299
10255
  // TODO(emily): Sometimes, we call `.remove()` but then hold a
10300
10256
  // reference to this object, and sometimes call `.toFront` on it.
@@ -10303,152 +10259,205 @@ const WrappedDefaults = ___default["default"].extend({
10303
10259
  if (parentNode) {
10304
10260
  parentNode.appendChild(this.wrapper);
10305
10261
  }
10306
- },
10307
- toBack: function () {
10262
+ }
10263
+ toBack() {
10308
10264
  const parentNode = this.wrapper.parentNode;
10309
- if (parentNode.firstChild !== this.wrapper) {
10265
+ if (parentNode != null && parentNode.firstChild !== this.wrapper) {
10310
10266
  parentNode.insertBefore(this.wrapper, parentNode.firstChild);
10311
10267
  }
10312
- },
10313
- remove: function () {
10268
+ }
10269
+ remove() {
10314
10270
  this.visibleShape.remove();
10315
10271
  $__default["default"](this.wrapper).remove();
10316
- },
10317
- getMouseTarget: function () {
10272
+ }
10273
+ getMouseTarget() {
10318
10274
  return this.visibleShape[0];
10319
- },
10320
- moveTo: function (point) {
10275
+ }
10276
+ moveTo(point) {
10321
10277
  const delta = kmath.vector.subtract(this.graphie.scalePoint(point), this.graphie.scalePoint(this.initialPoint));
10322
10278
  const do3dTransform = InteractiveUtil.getCanUse3dTransform();
10323
10279
  const transformation = "translateX(" + delta[0] + "px) " + "translateY(" + delta[1] + "px)" + (do3dTransform ? " translateZ(0)" : "");
10324
10280
  this.transform(transformation);
10325
- },
10326
- hide: function () {
10281
+ }
10282
+ hide() {
10327
10283
  this.visibleShape.hide();
10328
- },
10329
- show: function () {
10284
+ }
10285
+ show() {
10330
10286
  this.visibleShape.show();
10331
10287
  }
10332
- }, objective_.mapObjectFromArray(PASS_TO_RAPHAEL, function (attribute) {
10333
- return function () {
10334
- // @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
10335
- this.visibleShape[attribute](...arguments);
10336
- };
10337
- }));
10288
+ attr() {
10289
+ this.visibleShape.attr(...arguments);
10290
+ }
10291
+ animate() {
10292
+ this.visibleShape.animate(...arguments);
10293
+ }
10294
+ }
10338
10295
 
10339
10296
  const DEFAULT_OPTIONS$2 = {
10340
- maxScale: 1,
10341
- mouselayer: false,
10342
- shadow: false,
10343
- disableMouseEventsOnWrapper: false
10297
+ center: null,
10298
+ // gets ignored in `graphie.fixedPath` if `null`
10299
+ createPath: null,
10300
+ // gets defaulted in `graphie.fixedPath` if `null`
10301
+ mouselayer: false
10344
10302
  };
10345
- const WrappedEllipse = function (graphie, center, radii, options) {
10346
- options = ___default["default"].extend({}, DEFAULT_OPTIONS$2, options);
10347
-
10348
- // Add `wrapper`, `visibleShape`, and remaining properties.
10349
- const fixedEllipse = graphie.fixedEllipse(center, radii, options.maxScale, options.padding);
10350
- // @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
10351
- ___default["default"].extend(this, fixedEllipse, {
10352
- graphie: graphie,
10353
- initialPoint: center
10354
- });
10355
- if (options.interactiveKindForTesting) {
10356
- // @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
10357
- this.wrapper.setAttribute("data-interactive-kind-for-testing", options.interactiveKindForTesting);
10303
+ class WrappedPath extends WrappedDrawing {
10304
+ constructor(graphie, points, options) {
10305
+ const initialPoint = graphie.scalePoint(___default["default"].head(points));
10306
+ super(graphie, initialPoint);
10307
+ options = ___default["default"].extend({}, DEFAULT_OPTIONS$2, options);
10308
+ const fixedPath = graphie.fixedPath(points, options.center, options.createPath);
10309
+ this.wrapper = fixedPath.wrapper;
10310
+ this.visibleShape = fixedPath.visibleShape;
10311
+
10312
+ // Add to appropriate graphie layer
10313
+ if (options.mouselayer) {
10314
+ // Disable browser handling of all panning and zooming gestures on the
10315
+ // movable wrapper so that when moved the browser does not scroll page
10316
+ this.wrapper.style.touchAction = "none";
10317
+ this.graphie.addToMouseLayerWrapper(this.wrapper);
10318
+ } else {
10319
+ this.graphie.addToVisibleLayerWrapper(this.wrapper);
10320
+ }
10358
10321
  }
10322
+ }
10359
10323
 
10360
- // Add to appropriate graphie layer
10361
- if (options.mouselayer) {
10362
- // Disable browser handling of all panning and zooming gestures on the
10363
- // movable wrapper so that when moved the browser does not scroll page
10364
- // @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
10365
- this.wrapper.style.touchAction = "none";
10366
-
10367
- // @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.
10368
- this.graphie.addToMouseLayerWrapper(this.wrapper);
10369
- } else {
10370
- // @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.
10371
- this.graphie.addToVisibleLayerWrapper(this.wrapper);
10324
+ class Arrowhead extends WrappedPath {
10325
+ static scale = 1.4;
10326
+ constructor(graphie, style) {
10327
+ // Points that define the arrowhead
10328
+ const center = [0.75, 0];
10329
+ const points = [[-3, 4], [-2.75, 2.5], [0, 0.25], center, [0, -0.25], [-2.75, -2.5], [-3, -4]].map(point => {
10330
+ // Scale points by `Arrowhead.scale` around `center`
10331
+ const pv = kmath.vector.subtract(point, center);
10332
+ const pvScaled = kmath.vector.scale(pv, Arrowhead.scale);
10333
+ return kmath.vector.add(center, pvScaled);
10334
+ });
10335
+ const unscaledPoints = points.map(graphie.unscalePoint);
10336
+ super(graphie, unscaledPoints, {
10337
+ center: graphie.unscalePoint(center),
10338
+ createPath: createCubicPath
10339
+ });
10340
+ this.center = center;
10341
+ this.attr(___default["default"].extend({
10342
+ "stroke-linejoin": "round",
10343
+ "stroke-linecap": "round",
10344
+ "stroke-dasharray": ""
10345
+ }, style));
10372
10346
  }
10373
- if (options.shadow) {
10374
- const filter = "drop-shadow(0px 0px 5px rgba(0, 0, 0, 0.5))";
10375
- // @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
10376
- const wrapper = this.wrapper;
10377
- wrapper.style.filter = filter;
10378
-
10379
- // @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
10380
- this.moveTo = function (point) {
10381
- const delta = kmath.vector.subtract(this.graphie.scalePoint(point), this.graphie.scalePoint(this.initialPoint));
10382
- const do3dTransform = InteractiveUtil.getCanUse3dTransform();
10383
- const transform = "translateX(" + Math.round(delta[0]) + "px) " + "translateY(" + Math.round(delta[1]) + "px)" + (do3dTransform ? " translateZ(0)" : "");
10384
- this.transform(transform);
10385
- };
10347
+ toCoordAtAngle(coord, angle) {
10348
+ const clipPoint = this.graphie.scalePoint(getClipPoint(this.graphie, coord, angle));
10349
+ 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)");
10386
10350
  }
10387
- if (options.disableMouseEventsOnWrapper) {
10388
- // @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
10389
- this.wrapper.style.pointerEvents = "none";
10390
- // @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
10391
- this.visibleShape.node.style.pointerEvents = "auto";
10351
+ }
10352
+
10353
+ // We can't just pass in a path to `graph.fixedPath` as we need to modify
10354
+ // the points in some way, so instead we provide a function for creating
10355
+ // the path once the points have been transformed
10356
+ const createCubicPath = function (points) {
10357
+ let path = "M" + points[0][0] + " " + points[0][1];
10358
+ for (let i = 1; i < points.length; i += 3) {
10359
+ path += "C" + points[i][0] + " " + points[i][1] + " " + points[i + 1][0] + " " + points[i + 1][1] + " " + points[i + 2][0] + " " + points[i + 2][1];
10392
10360
  }
10361
+ return path;
10393
10362
  };
10394
- ___default["default"].extend(WrappedEllipse.prototype, WrappedDefaults);
10395
10363
 
10396
10364
  const DEFAULT_OPTIONS$1 = {
10397
- thickness: 2,
10398
- mouselayer: false
10365
+ maxScale: 1,
10366
+ mouselayer: false,
10367
+ shadow: false,
10368
+ disableMouseEventsOnWrapper: false
10399
10369
  };
10400
- const WrappedLine = function (graphie, start, end, options) {
10401
- options = ___default["default"].extend({}, DEFAULT_OPTIONS$1, options);
10370
+ class WrappedEllipse extends WrappedDrawing {
10371
+ constructor(graphie, center, radii, options) {
10372
+ super(graphie, center);
10373
+ options = ___default["default"].extend({}, DEFAULT_OPTIONS$1, options);
10402
10374
 
10403
- // Always make the line as large as possible and horizontal; this
10404
- // simplifies a lot of the transforms, e.g., we can rotate by exactly the
10405
- // angle of the argument points in `moveTo`.
10406
- const initialStart = [graphie.range[0][0], 0];
10407
- const initialEnd = [graphie.range[0][1], 0];
10375
+ // Add `wrapper`, `visibleShape`, and remaining properties.
10376
+ const fixedEllipse = graphie.fixedEllipse(center, radii, options.maxScale, options.padding);
10377
+ this.visibleShape = fixedEllipse.visibleShape;
10378
+ this.wrapper = fixedEllipse.wrapper;
10379
+ this.graphie = graphie;
10380
+ this.initialPoint = center;
10381
+ if (options.interactiveKindForTesting) {
10382
+ this.wrapper.setAttribute("data-interactive-kind-for-testing", options.interactiveKindForTesting);
10383
+ }
10408
10384
 
10409
- // Add `wrapper` and `visibleShape`
10410
- ___default["default"].extend(
10411
- // @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
10412
- this, graphie.fixedLine(initialStart, initialEnd, options.thickness));
10413
- if (options.interactiveKindForTesting) {
10414
- // @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
10415
- this.wrapper.setAttribute("data-interactive-kind-for-testing", options.interactiveKindForTesting);
10385
+ // Add to appropriate graphie layer
10386
+ if (options.mouselayer) {
10387
+ // Disable browser handling of all panning and zooming gestures on the
10388
+ // movable wrapper so that when moved the browser does not scroll page
10389
+ this.wrapper.style.touchAction = "none";
10390
+ this.graphie.addToMouseLayerWrapper(this.wrapper);
10391
+ } else {
10392
+ this.graphie.addToVisibleLayerWrapper(this.wrapper);
10393
+ }
10394
+ if (options.shadow) {
10395
+ const filter = "drop-shadow(0px 0px 5px rgba(0, 0, 0, 0.5))";
10396
+ const wrapper = this.wrapper;
10397
+ wrapper.style.filter = filter;
10398
+ this.moveTo = function (point) {
10399
+ const delta = kmath.vector.subtract(this.graphie.scalePoint(point), this.graphie.scalePoint(this.initialPoint));
10400
+ const do3dTransform = InteractiveUtil.getCanUse3dTransform();
10401
+ const transform = "translateX(" + Math.round(delta[0]) + "px) " + "translateY(" + Math.round(delta[1]) + "px)" + (do3dTransform ? " translateZ(0)" : "");
10402
+ this.transform(transform);
10403
+ };
10404
+ }
10405
+ if (options.disableMouseEventsOnWrapper) {
10406
+ this.wrapper.style.pointerEvents = "none";
10407
+ // @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
10408
+ this.visibleShape.node.style.pointerEvents = "auto";
10409
+ }
10416
10410
  }
10411
+ }
10417
10412
 
10418
- // @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
10419
- this.visibleShape.attr(options.normalStyle);
10420
-
10421
- // Save properties for computing transformations
10422
- // @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
10423
- ___default["default"].extend(this, {
10424
- graphie: graphie,
10425
- initialPoint: graphie.scalePoint(initialStart),
10426
- initialLength: kmath.point.distanceToPoint(graphie.scalePoint(initialStart), graphie.scalePoint(initialEnd))
10427
- });
10428
-
10429
- // Add to appropriate graphie layer
10430
- if (options.mouselayer) {
10431
- // Disable browser handling of all panning and zooming gestures on the
10432
- // movable wrapper so that when moved the browser does not scroll page
10433
- // @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
10434
- this.wrapper.style.touchAction = "none";
10413
+ const DEFAULT_OPTIONS = {
10414
+ thickness: 2,
10415
+ mouselayer: false
10416
+ };
10417
+ class WrappedLine extends WrappedDrawing {
10418
+ constructor(graphie, start, end, options) {
10419
+ // Always make the line as large as possible and horizontal; this
10420
+ // simplifies a lot of the transforms, e.g., we can rotate by exactly the
10421
+ // angle of the argument points in `moveTo`.
10422
+ const initialStart = [graphie.range[0][0], 0];
10423
+ const initialEnd = [graphie.range[0][1], 0];
10424
+ const initialPoint = graphie.scalePoint(initialStart);
10425
+ super(graphie, initialPoint);
10426
+ options = ___default["default"].extend({}, DEFAULT_OPTIONS, options);
10427
+ const fixedLine = graphie.fixedLine(initialStart, initialEnd, options.thickness);
10428
+ this.wrapper = fixedLine.wrapper;
10429
+ this.visibleShape = fixedLine.visibleShape;
10430
+ if (options.interactiveKindForTesting) {
10431
+ this.wrapper.setAttribute("data-interactive-kind-for-testing", options.interactiveKindForTesting);
10432
+ }
10433
+ this.visibleShape.attr(options.normalStyle);
10434
+
10435
+ // Save properties for computing transformations
10436
+ this.initialPoint = initialPoint;
10437
+ this.initialLength = kmath.point.distanceToPoint(graphie.scalePoint(initialStart), graphie.scalePoint(initialEnd));
10438
+
10439
+ // Add to appropriate graphie layer
10440
+ if (options.mouselayer) {
10441
+ // Disable browser handling of all panning and zooming gestures on the
10442
+ // movable wrapper so that when moved the browser does not scroll page
10443
+ this.wrapper.style.touchAction = "none";
10444
+ this.graphie.addToMouseLayerWrapper(this.wrapper);
10445
+ } else {
10446
+ this.graphie.addToVisibleLayerWrapper(this.wrapper);
10447
+ }
10435
10448
 
10436
- // @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.
10437
- this.graphie.addToMouseLayerWrapper(this.wrapper);
10438
- } else {
10439
- // @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.
10440
- this.graphie.addToVisibleLayerWrapper(this.wrapper);
10449
+ // Move line to initial points
10450
+ this.moveTo(start, end);
10441
10451
  }
10442
-
10443
- // Move to argument points
10444
- // @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
10445
- this.moveTo(start, end);
10446
- };
10447
- ___default["default"].extend(WrappedLine.prototype, WrappedDefaults, {
10448
- getMouseTarget: function () {
10452
+ getMouseTarget() {
10449
10453
  return this.wrapper;
10450
- },
10451
- moveTo: function (start, end) {
10454
+ }
10455
+
10456
+ // TODO(benchristel): we need to suppress a type error here because moveTo
10457
+ // takes 2 parameters here, but only 1 parameter in the superclass's
10458
+ // definition. Rename this method after confirming it's safe to do so
10459
+ // @ts-expect-error - TS2416: Property 'moveTo' in type 'WrappedLine' is not assignable to the same property in base type 'WrappedDefaults'.
10460
+ moveTo(start, end) {
10452
10461
  const scaledStart = this.graphie.scalePoint(start);
10453
10462
  const scaledEnd = this.graphie.scalePoint(end);
10454
10463
 
@@ -10464,45 +10473,7 @@ ___default["default"].extend(WrappedLine.prototype, WrappedDefaults, {
10464
10473
  const transformation = "translateX(" + delta[0] + "px) " + "translateY(" + delta[1] + "px) " + (do3dTransform ? " translateZ(0)" : "") + "rotate(" + angle + "deg) " + "scaleX(" + scale + ") scaleY(1)";
10465
10474
  this.transform(transformation);
10466
10475
  }
10467
- });
10468
-
10469
- const DEFAULT_OPTIONS = {
10470
- center: null,
10471
- // gets ignored in `graphie.fixedPath` if `null`
10472
- createPath: null,
10473
- // gets defaulted in `graphie.fixedPath` if `null`
10474
- mouselayer: false
10475
- };
10476
- const WrappedPath = function (graphie, points, options) {
10477
- options = ___default["default"].extend({}, DEFAULT_OPTIONS, options);
10478
-
10479
- // Add `wrapper` and `visibleShape`
10480
- ___default["default"].extend(
10481
- // @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
10482
- this, graphie.fixedPath(points, options.center, options.createPath));
10483
-
10484
- // Add remaining properties
10485
- // @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
10486
- ___default["default"].extend(this, {
10487
- graphie: graphie,
10488
- initialPoint: graphie.scalePoint(___default["default"].head(points))
10489
- });
10490
-
10491
- // Add to appropriate graphie layer
10492
- if (options.mouselayer) {
10493
- // Disable browser handling of all panning and zooming gestures on the
10494
- // movable wrapper so that when moved the browser does not scroll page
10495
- // @ts-expect-error - TS2683 - 'this' implicitly has type 'any' because it does not have a type annotation.
10496
- this.wrapper.style.touchAction = "none";
10497
-
10498
- // @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.
10499
- this.graphie.addToMouseLayerWrapper(this.wrapper);
10500
- } else {
10501
- // @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.
10502
- this.graphie.addToVisibleLayerWrapper(this.wrapper);
10503
- }
10504
- };
10505
- ___default["default"].extend(WrappedPath.prototype, WrappedDefaults);
10476
+ }
10506
10477
 
10507
10478
  /**
10508
10479
  * A collection of geomtry-related utility functions
@@ -10728,9 +10699,6 @@ firstPoints, secondPoints) {
10728
10699
  }
10729
10700
 
10730
10701
  /* eslint-disable @babel/no-invalid-this */
10731
- const {
10732
- getCanUse3dTransform
10733
- } = InteractiveUtil;
10734
10702
  function scaledDistanceFromAngle(angle) {
10735
10703
  const a = 3.51470560176242 * 20;
10736
10704
  const b = 0.5687298702748785 * 20;
@@ -11614,52 +11582,15 @@ ___default["default"].extend(GraphUtils.Graphie.prototype, {
11614
11582
  ___default["default"].each(elements, function (element) {
11615
11583
  element.moveTo(start, end);
11616
11584
  });
11617
- const createArrow = function (graph, style) {
11618
- const center = [0.75, 0];
11619
- let points = [[-3, 4], [-2.75, 2.5], [0, 0.25], center, [0, -0.25], [-2.75, -2.5], [-3, -4]];
11620
- const scale = 1.4;
11621
- points = ___default["default"].map(points, function (point) {
11622
- const pv = kmath.vector.subtract(point, center);
11623
- const pvScaled = kmath.vector.scale(pv, scale);
11624
- return kmath.vector.add(center, pvScaled);
11625
- });
11626
- const createCubicPath = function (points) {
11627
- let path = "M" + points[0][0] + " " + points[0][1];
11628
- for (let i = 1; i < points.length; i += 3) {
11629
- path += "C" + points[i][0] + " " + points[i][1] + " " + points[i + 1][0] + " " + points[i + 1][1] + " " + points[i + 2][0] + " " + points[i + 2][1];
11630
- }
11631
- return path;
11632
- };
11633
- const unscaledPoints = ___default["default"].map(points, graph.unscalePoint);
11634
- const options = {
11635
- center: graph.unscalePoint(center),
11636
- createPath: createCubicPath
11637
- };
11638
- const arrowHead = new WrappedPath(graph, unscaledPoints, options);
11639
- arrowHead.attr(___default["default"].extend({
11640
- "stroke-linejoin": "round",
11641
- "stroke-linecap": "round",
11642
- "stroke-dasharray": ""
11643
- }, style));
11644
-
11645
- // Add custom function for transforming arrowheads that
11646
- // accounts for center, scaling, etc.
11647
- arrowHead.toCoordAtAngle = function (coord, angle) {
11648
- const clipPoint = graph.scalePoint(getClipPoint(graph, coord, angle));
11649
- const do3dTransform = getCanUse3dTransform();
11650
- 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)");
11651
- };
11652
- return arrowHead;
11653
- };
11654
11585
 
11655
11586
  // Add arrows
11656
11587
  if (this._arrows == null) {
11657
11588
  this._arrows = [];
11658
11589
  if (this.extendLine) {
11659
- this._arrows.push(createArrow(graph, this.normalStyle));
11660
- this._arrows.push(createArrow(graph, this.normalStyle));
11590
+ this._arrows.push(new Arrowhead(graph, this.normalStyle));
11591
+ this._arrows.push(new Arrowhead(graph, this.normalStyle));
11661
11592
  } else if (this.extendRay) {
11662
- this._arrows.push(createArrow(graph, this.normalStyle));
11593
+ this._arrows.push(new Arrowhead(graph, this.normalStyle));
11663
11594
  }
11664
11595
  }
11665
11596
  const coordForArrow = [this.coordA, this.coordZ];
@@ -14100,78 +14031,6 @@ const getScaledAngle = function (line) {
14100
14031
  return kmath.vector.polarDegFromCart(kmath.vector.subtract(scaledZ, scaledA))[1];
14101
14032
  };
14102
14033
 
14103
- // Given `coord` and `angle`, find the point where a line extended
14104
- // from `coord` in the direction of `angle` would be clipped by the
14105
- // edge of the graphie canvas. Then draw an arrowhead at that point
14106
- // pointing in the direction of `angle`.
14107
- const getClipPoint = function (graph, coord, angle) {
14108
- // Actually put the arrowheads 4px from the edge so they have
14109
- // a bit of room
14110
- const xExtent = graph.range[0][1] - graph.range[0][0];
14111
- const yExtent = graph.range[1][1] - graph.range[1][0];
14112
-
14113
- // shoot a point off into the distance ...
14114
- const distance = xExtent + yExtent;
14115
- // we need to scale the point according to the scale of the axes
14116
- const angleVec = graph.unscaleVector(kmath.vector.cartFromPolarDeg(1, angle));
14117
- const distVec = kmath.vector.scale(kmath.vector.normalize(angleVec), distance);
14118
- const farCoord = kmath.vector.add(coord, distVec);
14119
- const scaledAngle = kmath.vector.polarDegFromCart(angleVec)[1];
14120
- // ... and then bring it back
14121
- const clipPoint = graph.constrainToBoundsOnAngle(farCoord, 4, scaledAngle * Math.PI / 180);
14122
- return clipPoint;
14123
- };
14124
-
14125
- // Given `coord` and `angle`, find the point where a line extended
14126
- // from `coord` in the direction of `angle` would be clipped by the
14127
- // edge of the graphie canvas. Then draw an arrowhead at that point
14128
- // pointing in the direction of `angle`.
14129
- const createArrow = function (graph, style) {
14130
- // Points that define the arrowhead
14131
- const center = [0.75, 0];
14132
- let points = [[-3, 4], [-2.75, 2.5], [0, 0.25], center, [0, -0.25], [-2.75, -2.5], [-3, -4]];
14133
-
14134
- // Scale points by 1.4 around (0.75, 0)
14135
- const scale = 1.4;
14136
- points = ___default["default"].map(points, function (point) {
14137
- const pv = kmath.vector.subtract(point, center);
14138
- const pvScaled = kmath.vector.scale(pv, scale);
14139
- return kmath.vector.add(center, pvScaled);
14140
- });
14141
-
14142
- // We can't just pass in a path to `graph.fixedPath` as we need to modify
14143
- // the points in some way, so instead we provide a function for creating
14144
- // the path once the points have been transformed
14145
- const createCubicPath = function (points) {
14146
- let path = "M" + points[0][0] + " " + points[0][1];
14147
- for (let i = 1; i < points.length; i += 3) {
14148
- path += "C" + points[i][0] + " " + points[i][1] + " " + points[i + 1][0] + " " + points[i + 1][1] + " " + points[i + 2][0] + " " + points[i + 2][1];
14149
- }
14150
- return path;
14151
- };
14152
-
14153
- // Create arrowhead
14154
- const unscaledPoints = ___default["default"].map(points, graph.unscalePoint);
14155
- const options = {
14156
- center: graph.unscalePoint(center),
14157
- createPath: createCubicPath
14158
- };
14159
- const arrowHead = new WrappedPath(graph, unscaledPoints, options);
14160
- arrowHead.attr(___default["default"].extend({
14161
- "stroke-linejoin": "round",
14162
- "stroke-linecap": "round",
14163
- "stroke-dasharray": ""
14164
- }, style));
14165
-
14166
- // Add custom function for transforming arrowheads that accounts for
14167
- // center, scaling, etc.
14168
- arrowHead.toCoordAtAngle = function (coord, angle) {
14169
- const clipPoint = graph.scalePoint(getClipPoint(graph, coord, angle));
14170
- arrowHead.transform("translateX(" + (clipPoint[0] + scale * center[0]) + "px) " + "translateY(" + (clipPoint[1] + scale * center[1]) + "px) " + "translateZ(0) " + "rotate(" + (360 - KhanMath.bound(angle)) + "deg)");
14171
- };
14172
- return arrowHead;
14173
- };
14174
-
14175
14034
  /**
14176
14035
  * MovableLine option functions
14177
14036
  */
@@ -14258,16 +14117,16 @@ const draw$3 = {
14258
14117
  // @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'?
14259
14118
  this._arrows.push(
14260
14119
  // @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; }'.
14261
- createArrow(this.graphie, this.normalStyle()));
14120
+ new Arrowhead(this.graphie, this.normalStyle()));
14262
14121
  // @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'?
14263
14122
  this._arrows.push(
14264
14123
  // @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; }'.
14265
- createArrow(this.graphie, this.normalStyle()));
14124
+ new Arrowhead(this.graphie, this.normalStyle()));
14266
14125
  } else if (state.extendRay) {
14267
14126
  // @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'?
14268
14127
  this._arrows.push(
14269
14128
  // @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; }'.
14270
- createArrow(this.graphie, this.normalStyle()));
14129
+ new Arrowhead(this.graphie, this.normalStyle()));
14271
14130
  }
14272
14131
  }
14273
14132
 
@@ -14413,6 +14272,75 @@ var MovableLineOptions = {
14413
14272
  }
14414
14273
  };
14415
14274
 
14275
+ /**
14276
+ * A work-in-progress of _ methods for objects.
14277
+ * That is, they take an object as a parameter,
14278
+ * and return an object instead of an array.
14279
+ *
14280
+ * TODO(aria): Move this out of interactive2
14281
+ */
14282
+
14283
+ /**
14284
+ * Does a pluck on keys inside objects in an object
14285
+ *
14286
+ * Ex:
14287
+ * tools = {
14288
+ * translation: {
14289
+ * enabled: true
14290
+ * },
14291
+ * rotation: {
14292
+ * enabled: false
14293
+ * }
14294
+ * };
14295
+ * pluckObject(tools, "enabled") returns {
14296
+ * translation: true
14297
+ * rotation: false
14298
+ * }
14299
+ */
14300
+ const pluck = function (table, subKey) {
14301
+ return ___default["default"].object(___default["default"].map(table, function (value, key) {
14302
+ return [key, value[subKey]];
14303
+ }));
14304
+ };
14305
+
14306
+ /**
14307
+ * Maps an object to an object
14308
+ *
14309
+ * > mapObject({a: '1', b: '2'}, (value, key) => {
14310
+ * return value + 1;
14311
+ * });
14312
+ * {a: 2, b: 3}
14313
+ */
14314
+ const mapObject$2 = function (obj, lambda) {
14315
+ const result = {};
14316
+ ___default["default"].each(___default["default"].keys(obj), function (key) {
14317
+ // @ts-expect-error - TS2345 - Argument of type 'string' is not assignable to parameter of type 'K'.
14318
+ result[key] = lambda(obj[key], key);
14319
+ });
14320
+ return result;
14321
+ };
14322
+
14323
+ /**
14324
+ * Maps an array to an object
14325
+ *
14326
+ * > mapObjectFromArray(['a', 'b'], function(elem) {
14327
+ * return elem + elem;
14328
+ * });
14329
+ * {a: 'aa', b: 'bb'}
14330
+ */
14331
+ const mapObjectFromArray$1 = function (arr, lambda) {
14332
+ const result = {};
14333
+ ___default["default"].each(arr, function (elem) {
14334
+ result[elem] = lambda(elem);
14335
+ });
14336
+ return result;
14337
+ };
14338
+ var objective_ = {
14339
+ pluck: pluck,
14340
+ mapObject: mapObject$2,
14341
+ mapObjectFromArray: mapObjectFromArray$1
14342
+ };
14343
+
14416
14344
  /**
14417
14345
  * MovableLine
14418
14346
  */
@@ -17975,33 +17903,33 @@ class Lint extends React__namespace.Component {
17975
17903
  let warningText;
17976
17904
  let warningTextStyle;
17977
17905
  if (this.props.severity === Severity.Error) {
17978
- severityStyle = styles$A.indicatorError;
17906
+ severityStyle = styles$B.indicatorError;
17979
17907
  warningText = "Error";
17980
- warningTextStyle = styles$A.publishBlockingError;
17908
+ warningTextStyle = styles$B.publishBlockingError;
17981
17909
  } else if (this.props.severity === Severity.Warning) {
17982
- severityStyle = styles$A.indicatorWarning;
17910
+ severityStyle = styles$B.indicatorWarning;
17983
17911
  warningText = "Warning";
17984
- warningTextStyle = styles$A.warning;
17912
+ warningTextStyle = styles$B.warning;
17985
17913
  } else {
17986
- severityStyle = styles$A.indicatorGuideline;
17914
+ severityStyle = styles$B.indicatorGuideline;
17987
17915
  warningText = "Recommendation";
17988
- warningTextStyle = styles$A.warning;
17916
+ warningTextStyle = styles$B.warning;
17989
17917
  }
17990
17918
  return /*#__PURE__*/React__namespace.createElement("a", {
17991
17919
  href: `https://khanacademy.org/r/linter-rules#${this.props.ruleName}`,
17992
17920
  target: "lint-help-window",
17993
17921
  className: aphrodite.css(style)
17994
17922
  }, /*#__PURE__*/React__namespace.createElement("span", {
17995
- className: aphrodite.css(styles$A.indicator, severityStyle)
17923
+ className: aphrodite.css(styles$B.indicator, severityStyle)
17996
17924
  }, this.props.severity === 1 && /*#__PURE__*/React__namespace.createElement(InlineIcon, exclamationIcon)), /*#__PURE__*/React__namespace.createElement("div", {
17997
- className: aphrodite.css(styles$A.tooltip, tooltipAbove && styles$A.tooltipAbove)
17925
+ className: aphrodite.css(styles$B.tooltip, tooltipAbove && styles$B.tooltipAbove)
17998
17926
  }, this.props.message.split("\n\n").map((m, i) => /*#__PURE__*/React__namespace.createElement("p", {
17999
17927
  key: i,
18000
- className: aphrodite.css(styles$A.tooltipParagraph)
17928
+ className: aphrodite.css(styles$B.tooltipParagraph)
18001
17929
  }, /*#__PURE__*/React__namespace.createElement("span", {
18002
17930
  className: aphrodite.css(warningTextStyle)
18003
17931
  }, warningText, ":", " "), m)), /*#__PURE__*/React__namespace.createElement("div", {
18004
- className: aphrodite.css(styles$A.tail, tooltipAbove && styles$A.tailAbove)
17932
+ className: aphrodite.css(styles$B.tail, tooltipAbove && styles$B.tailAbove)
18005
17933
  })));
18006
17934
  };
18007
17935
 
@@ -18029,20 +17957,20 @@ class Lint extends React__namespace.Component {
18029
17957
  }
18030
17958
  if (blockHighlight) {
18031
17959
  return /*#__PURE__*/React__namespace.createElement("span", {
18032
- className: aphrodite.css(styles$A.lintContainer, styles$A.lintContainerBlock)
18033
- }, this.renderLink(styles$A.radioWidgetHoverTarget), /*#__PURE__*/React__namespace.createElement("span", null, children));
17960
+ className: aphrodite.css(styles$B.lintContainer, styles$B.lintContainerBlock)
17961
+ }, this.renderLink(styles$B.radioWidgetHoverTarget), /*#__PURE__*/React__namespace.createElement("span", null, children));
18034
17962
  }
18035
17963
  if (inline) {
18036
17964
  return /*#__PURE__*/React__namespace.createElement("span", {
18037
- className: aphrodite.css(styles$A.lintContainer)
18038
- }, this.renderLink(styles$A.inlineHoverTarget), /*#__PURE__*/React__namespace.createElement("span", null, children));
17965
+ className: aphrodite.css(styles$B.lintContainer)
17966
+ }, this.renderLink(styles$B.inlineHoverTarget), /*#__PURE__*/React__namespace.createElement("span", null, children));
18039
17967
  }
18040
17968
  return /*#__PURE__*/React__namespace.createElement("div", {
18041
- className: aphrodite.css(styles$A.lintContainer)
18042
- }, this.renderLink(styles$A.hoverTarget), /*#__PURE__*/React__namespace.createElement("div", null, children));
17969
+ className: aphrodite.css(styles$B.lintContainer)
17970
+ }, this.renderLink(styles$B.hoverTarget), /*#__PURE__*/React__namespace.createElement("div", null, children));
18043
17971
  }
18044
17972
  }
18045
- const styles$A = aphrodite.StyleSheet.create({
17973
+ const styles$B = aphrodite.StyleSheet.create({
18046
17974
  // This is the class of the outermost element.
18047
17975
  // We use relative positioning so that the lint indicator can be
18048
17976
  // positioned absolutely relative to the position of the linty container.
@@ -20144,7 +20072,7 @@ class Renderer extends React__namespace.Component {
20144
20072
  };
20145
20073
  const mobileInnerStyle = {
20146
20074
  ...innerStyle,
20147
- ...styles$z.mobileZoomableParentFix
20075
+ ...styles$A.mobileZoomableParentFix
20148
20076
  };
20149
20077
  return /*#__PURE__*/React__namespace.createElement("div", {
20150
20078
  key: state.key,
@@ -20281,7 +20209,7 @@ class Renderer extends React__namespace.Component {
20281
20209
  };
20282
20210
  const mobileInnerStyle = {
20283
20211
  ...innerStyle,
20284
- ...styles$z.mobileZoomableParentFix
20212
+ ...styles$A.mobileZoomableParentFix
20285
20213
  };
20286
20214
  const wrappedOutput = /*#__PURE__*/React__namespace.createElement("div", {
20287
20215
  style: {
@@ -20789,7 +20717,7 @@ class Renderer extends React__namespace.Component {
20789
20717
  return this.lastRenderedMarkdown;
20790
20718
  }
20791
20719
  }
20792
- const styles$z = {
20720
+ const styles$A = {
20793
20721
  mobileZoomableParentFix: {
20794
20722
  // NOTE(abdul): There is an issue where transform animations will
20795
20723
  // cause the Zoomable component to disappear when running on the
@@ -21724,10 +21652,10 @@ class InputNumber extends React__namespace.Component {
21724
21652
  // Note: This is _very_ similar to what `numeric-input.jsx` does. If
21725
21653
  // you modify this, double-check if you also need to modify that
21726
21654
  // component.
21727
- const inputStyles = [styles$y.default, this.props.size === "small" ? styles$y.small : null, this.props.rightAlign ? styles$y.rightAlign : styles$y.leftAlign];
21655
+ const inputStyles = [styles$z.default, this.props.size === "small" ? styles$z.small : null, this.props.rightAlign ? styles$z.rightAlign : styles$z.leftAlign];
21728
21656
  // Unanswered
21729
21657
  if (rubric && !this.props.currentValue) {
21730
- inputStyles.push(styles$y.answerStateUnanswered);
21658
+ inputStyles.push(styles$z.answerStateUnanswered);
21731
21659
  }
21732
21660
  return /*#__PURE__*/React__namespace.createElement(InputWithExamples
21733
21661
  // eslint-disable-next-line react/no-string-refs
@@ -21875,7 +21803,7 @@ class InputNumber extends React__namespace.Component {
21875
21803
  return answerString;
21876
21804
  }
21877
21805
  }
21878
- const styles$y = aphrodite.StyleSheet.create({
21806
+ const styles$z = aphrodite.StyleSheet.create({
21879
21807
  default: {
21880
21808
  width: 80,
21881
21809
  height: "auto"
@@ -22873,7 +22801,7 @@ const FocusRing = function (props) {
22873
22801
  };
22874
22802
  return /*#__PURE__*/React__namespace.createElement("span", {
22875
22803
  "data-test-id": "focus-ring",
22876
- className: aphrodite.css(styles$x.ring),
22804
+ className: aphrodite.css(styles$y.ring),
22877
22805
  style: style
22878
22806
  }, children);
22879
22807
  };
@@ -22882,7 +22810,7 @@ FocusRing.defaultProps = {
22882
22810
  color: kaGreen$1,
22883
22811
  multipleSelect: false
22884
22812
  };
22885
- const styles$x = aphrodite.StyleSheet.create({
22813
+ const styles$y = aphrodite.StyleSheet.create({
22886
22814
  ring: {
22887
22815
  margin: "auto",
22888
22816
  display: "inline-block",
@@ -22919,7 +22847,7 @@ function getChoiceLetter(pos) {
22919
22847
  }
22920
22848
 
22921
22849
  const CHOICE_ICON_SIZE = 24;
22922
- const styles$w = aphrodite.StyleSheet.create({
22850
+ const styles$x = aphrodite.StyleSheet.create({
22923
22851
  iconWrapper: {
22924
22852
  display: "inline-block",
22925
22853
  position: "relative"
@@ -22942,7 +22870,7 @@ const CrossOutLine = function (props) {
22942
22870
  width: CROSS_OUT_LINE_SIZE,
22943
22871
  height: CROSS_OUT_LINE_SIZE,
22944
22872
  viewBox: `0 0 ${CROSS_OUT_LINE_SIZE} ${CROSS_OUT_LINE_SIZE}`,
22945
- className: aphrodite.css(styles$v.crossOutLine),
22873
+ className: aphrodite.css(styles$w.crossOutLine),
22946
22874
  "data-test-id": "choice-icon__cross-out-line"
22947
22875
  }, /*#__PURE__*/React__namespace.createElement("line", {
22948
22876
  // The line stretches from the bottom-left to top-right.
@@ -22957,7 +22885,7 @@ const CrossOutLine = function (props) {
22957
22885
  strokeLinecap: "round"
22958
22886
  }));
22959
22887
  };
22960
- const styles$v = aphrodite.StyleSheet.create({
22888
+ const styles$w = aphrodite.StyleSheet.create({
22961
22889
  crossOutLine: {
22962
22890
  // Center the icon within the container.
22963
22891
  position: "absolute",
@@ -23038,7 +22966,7 @@ const ChoiceIcon = function (props) {
23038
22966
  } = props;
23039
22967
  const dynamicStyles = getDynamicStyles(checked, showCorrectness, pressed, multipleSelect, correct);
23040
22968
  return /*#__PURE__*/React__namespace.createElement("div", {
23041
- className: aphrodite.css(styles$w.iconWrapper)
22969
+ className: aphrodite.css(styles$x.iconWrapper)
23042
22970
  }, /*#__PURE__*/React__namespace.createElement(FocusRing, {
23043
22971
  color: Color__default["default"].blue,
23044
22972
  visible: focused || hovered,
@@ -23047,13 +22975,13 @@ const ChoiceIcon = function (props) {
23047
22975
  // @ts-expect-error - TS2322 - Type '{ backgroundColor: string | null | undefined; borderColor: string; color: string; borderRadius: number; }' is not assignable to type 'Properties<string | number, string & {}>'.
23048
22976
  style: dynamicStyles,
23049
22977
  "data-test-id": "choice-icon__library-choice-icon",
23050
- className: aphrodite.css(styles$u.circle, showCorrectness && correct && styles$u.circleCorrect, showCorrectness && !correct && styles$u.circleIncorrect, showCorrectness && !correct && (checked || previouslyAnswered) && styles$u.circleIncorrectAnswered)
22978
+ className: aphrodite.css(styles$v.circle, showCorrectness && correct && styles$v.circleCorrect, showCorrectness && !correct && styles$v.circleIncorrect, showCorrectness && !correct && (checked || previouslyAnswered) && styles$v.circleIncorrectAnswered)
23051
22979
  // used in BaseRadio editMode to check
23052
22980
  // if we actually clicked on the radio icon
23053
22981
  ,
23054
22982
  "data-is-radio-icon": true
23055
22983
  }, /*#__PURE__*/React__namespace.createElement("div", {
23056
- className: aphrodite.css(styles$u.innerWrapper)
22984
+ className: aphrodite.css(styles$v.innerWrapper)
23057
22985
  }, /*#__PURE__*/React__namespace.createElement(ChoiceInner, {
23058
22986
  pos: pos,
23059
22987
  showCorrectness: showCorrectness,
@@ -23062,7 +22990,7 @@ const ChoiceIcon = function (props) {
23062
22990
  color: dynamicStyles.borderColor
23063
22991
  }));
23064
22992
  };
23065
- const styles$u = aphrodite.StyleSheet.create({
22993
+ const styles$v = aphrodite.StyleSheet.create({
23066
22994
  innerWrapper: {
23067
22995
  width: CHOICE_ICON_SIZE,
23068
22996
  height: CHOICE_ICON_SIZE,
@@ -23154,19 +23082,19 @@ const OptionStatus = function (props) {
23154
23082
  }
23155
23083
  let textStyle;
23156
23084
  if (correct) {
23157
- textStyle = styles$t.correct;
23085
+ textStyle = styles$u.correct;
23158
23086
  } else {
23159
23087
  if (checked || previouslyAnswered) {
23160
- textStyle = styles$t.incorrectAnswered;
23088
+ textStyle = styles$u.incorrectAnswered;
23161
23089
  } else {
23162
- textStyle = styles$t.incorrect;
23090
+ textStyle = styles$u.incorrect;
23163
23091
  }
23164
23092
  }
23165
23093
  return /*#__PURE__*/React__namespace.createElement("div", {
23166
- className: aphrodite.css(styles$t.text, textStyle)
23094
+ className: aphrodite.css(styles$u.text, textStyle)
23167
23095
  }, renderText(checked, correct, crossedOut));
23168
23096
  };
23169
- const styles$t = aphrodite.StyleSheet.create({
23097
+ const styles$u = aphrodite.StyleSheet.create({
23170
23098
  text: {
23171
23099
  alignItems: "center",
23172
23100
  display: "flex",
@@ -23240,8 +23168,8 @@ const Choice = function (props) {
23240
23168
  crossedOut: updatedCrossedOut
23241
23169
  });
23242
23170
  }
23243
- const descriptionClassName = classNames__default["default"]("description", aphrodite.css(styles$s.description));
23244
- const rationaleClassName = classNames__default["default"]("perseus-radio-rationale-content", aphrodite.css(styles$s.rationale));
23171
+ const descriptionClassName = classNames__default["default"]("description", aphrodite.css(styles$t.description));
23172
+ const rationaleClassName = classNames__default["default"]("perseus-radio-rationale-content", aphrodite.css(styles$t.rationale));
23245
23173
 
23246
23174
  // We want to show the choices as dimmed out when the choices are disabled.
23247
23175
  // However, we don't want to do this when we're in review mode in the
@@ -23412,7 +23340,7 @@ const Choice = function (props) {
23412
23340
  "data-test-id": `perseus-radio-rationale-content-${pos}`
23413
23341
  }, rationale));
23414
23342
  };
23415
- const styles$s = aphrodite.StyleSheet.create({
23343
+ const styles$t = aphrodite.StyleSheet.create({
23416
23344
  description: {
23417
23345
  display: "inline-block",
23418
23346
  width: "100%"
@@ -23604,10 +23532,10 @@ const BaseRadio = function (props) {
23604
23532
  const isMobile = apiOptions.isMobile;
23605
23533
  const firstChoiceHighlighted = choices[0].highlighted;
23606
23534
  const lastChoiceHighlighted = choices[choices.length - 1].highlighted;
23607
- const className = classNames__default["default"]("perseus-widget-radio", !editMode && "perseus-rendered-radio", aphrodite.css(styles$r.radio, styles$r.responsiveRadioContainer, firstChoiceHighlighted && isMobile && styles$r.radioContainerFirstHighlighted, lastChoiceHighlighted && isMobile && styles$r.radioContainerLastHighlighted));
23608
- const instructionsClassName = classNames__default["default"]("instructions", aphrodite.css(styles$r.instructions, isMobile && styles$r.instructionsMobile));
23535
+ const className = classNames__default["default"]("perseus-widget-radio", !editMode && "perseus-rendered-radio", aphrodite.css(styles$s.radio, styles$s.responsiveRadioContainer, firstChoiceHighlighted && isMobile && styles$s.radioContainerFirstHighlighted, lastChoiceHighlighted && isMobile && styles$s.radioContainerLastHighlighted));
23536
+ const instructionsClassName = classNames__default["default"]("instructions", aphrodite.css(styles$s.instructions, isMobile && styles$s.instructionsMobile));
23609
23537
  const instructions = getInstructionsText(multipleSelect, countChoices, numCorrect);
23610
- const responsiveClassName = aphrodite.css(styles$r.responsiveFieldset);
23538
+ const responsiveClassName = aphrodite.css(styles$s.responsiveFieldset);
23611
23539
  const fieldset = /*#__PURE__*/React__namespace.createElement("fieldset", {
23612
23540
  className: `perseus-widget-radio-fieldset ${responsiveClassName}`
23613
23541
  }, /*#__PURE__*/React__namespace.createElement("legend", {
@@ -23658,7 +23586,7 @@ const BaseRadio = function (props) {
23658
23586
  const aphroditeClassName = checked => {
23659
23587
  // Whether or not to show correctness borders
23660
23588
  // for this choice and the next choice.
23661
- return aphrodite.css(sharedStyles.aboveScratchpad, styles$r.item, styles$r.responsiveItem, checked && styles$r.selectedItem, checked && choice.highlighted && styles$r.aboveBackdrop, checked && choice.highlighted && apiOptions.isMobile && styles$r.aboveBackdropMobile, nextChoiceHighlighted && apiOptions.isMobile && styles$r.nextHighlighted);
23589
+ return aphrodite.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);
23662
23590
  };
23663
23591
 
23664
23592
  // HACK(abdulrahman): Preloads the selection-state
@@ -23732,14 +23660,14 @@ const BaseRadio = function (props) {
23732
23660
  // Allow for horizontal scrolling if content is too wide, which may be
23733
23661
  // an issue especially on phones.
23734
23662
  return /*#__PURE__*/React__namespace.createElement("div", {
23735
- className: aphrodite.css(styles$r.responsiveContainer)
23663
+ className: aphrodite.css(styles$s.responsiveContainer)
23736
23664
  }, fieldset);
23737
23665
  };
23738
23666
  BaseRadio.defaultProps = {
23739
23667
  editMode: false,
23740
23668
  multipleSelect: false
23741
23669
  };
23742
- const styles$r = aphrodite.StyleSheet.create({
23670
+ const styles$s = aphrodite.StyleSheet.create({
23743
23671
  instructions: {
23744
23672
  display: "block",
23745
23673
  color: gray17,
@@ -24398,9 +24326,9 @@ class Categorizer extends React__namespace.Component {
24398
24326
  indexedItems = Util.shuffle(indexedItems, this.props.problemNum);
24399
24327
  }
24400
24328
  const table = /*#__PURE__*/React__namespace.createElement("table", {
24401
- className: "categorizer-table " + aphrodite.css(styles$q.mobileTable)
24329
+ className: "categorizer-table " + aphrodite.css(styles$r.mobileTable)
24402
24330
  }, /*#__PURE__*/React__namespace.createElement("thead", null, /*#__PURE__*/React__namespace.createElement("tr", null, /*#__PURE__*/React__namespace.createElement("td", {
24403
- className: aphrodite.css(styles$q.emptyHeaderCell)
24331
+ className: aphrodite.css(styles$r.emptyHeaderCell)
24404
24332
  }), this.props.categories.map((category, i) => {
24405
24333
  // Array index is the correct key here, as that's
24406
24334
  // how category grading actually works -- no way
@@ -24408,7 +24336,7 @@ class Categorizer extends React__namespace.Component {
24408
24336
  // middle. (If we later add that, this should be
24409
24337
  // fixed.)
24410
24338
  return /*#__PURE__*/React__namespace.createElement("th", {
24411
- className: aphrodite.css(styles$q.header),
24339
+ className: aphrodite.css(styles$r.header),
24412
24340
  key: i
24413
24341
  }, /*#__PURE__*/React__namespace.createElement(Renderer, {
24414
24342
  content: category,
@@ -24428,7 +24356,7 @@ class Categorizer extends React__namespace.Component {
24428
24356
  })), self.props.categories.map((catName, catNum) => {
24429
24357
  const selected = self.props.values[itemNum] === catNum;
24430
24358
  return /*#__PURE__*/React__namespace.createElement("td", {
24431
- className: "category " + aphrodite.css(styles$q.cell),
24359
+ className: "category " + aphrodite.css(styles$r.cell),
24432
24360
  key: catNum
24433
24361
  }, /*#__PURE__*/React__namespace.createElement("div", {
24434
24362
  className: ClassNames.INTERACTIVE,
@@ -24447,7 +24375,7 @@ class Categorizer extends React__namespace.Component {
24447
24375
  onChange: this.onChange.bind(this, itemNum, catNum),
24448
24376
  onClick: e => e.stopPropagation()
24449
24377
  }), !isMobile && /*#__PURE__*/React__namespace.createElement("span", {
24450
- className: aphrodite.css(styles$q.radioSpan, selected && styles$q.checkedRadioSpan, this.props.static && selected && styles$q.staticCheckedRadioSpan)
24378
+ className: aphrodite.css(styles$r.radioSpan, selected && styles$r.checkedRadioSpan, this.props.static && selected && styles$r.staticCheckedRadioSpan)
24451
24379
  }, selected ? /*#__PURE__*/React__namespace.createElement(InlineIcon, iconCircle) : /*#__PURE__*/React__namespace.createElement(InlineIcon, iconCircleThin))));
24452
24380
  }));
24453
24381
  /* eslint-enable max-len */
@@ -24459,7 +24387,7 @@ class Categorizer extends React__namespace.Component {
24459
24387
  "categorizer-container": true,
24460
24388
  "static-mode": this.props.static
24461
24389
  });
24462
- const inlineStyles = this.props.apiOptions.isMobile ? [styles$q.fullBleedContainer] : [];
24390
+ const inlineStyles = this.props.apiOptions.isMobile ? [styles$r.fullBleedContainer] : [];
24463
24391
  return /*#__PURE__*/React__namespace.createElement("div", {
24464
24392
  className: extraClassNames + " " + aphrodite.css(...inlineStyles)
24465
24393
  }, table);
@@ -24508,7 +24436,7 @@ const pageMargin = 16;
24508
24436
 
24509
24437
  // Stylesheets aren't directly testable
24510
24438
  /* c8 ignore next */
24511
- const styles$q = aphrodite.StyleSheet.create({
24439
+ const styles$r = aphrodite.StyleSheet.create({
24512
24440
  mobileTable: {
24513
24441
  [mediaQueries.smOrSmaller]: {
24514
24442
  minWidth: "auto"
@@ -24618,7 +24546,7 @@ const toAbsoluteUrl = url => parseUrl(url).href;
24618
24546
  const {
24619
24547
  updateQueryString: updateQueryString$1
24620
24548
  } = Util;
24621
- function getUrlFromProgramID(programID) {
24549
+ function getUrlFromProgramID$1(programID) {
24622
24550
  const {
24623
24551
  InitialRequestUrl
24624
24552
  } = getDependencies();
@@ -24727,7 +24655,7 @@ class CSProgram extends React__namespace.Component {
24727
24655
  return /*#__PURE__*/React__namespace.createElement("div", null);
24728
24656
  }
24729
24657
  let styleContainer = false;
24730
- let url = getUrlFromProgramID(this.props.programID);
24658
+ let url = getUrlFromProgramID$1(this.props.programID);
24731
24659
  let className;
24732
24660
  const style = {
24733
24661
  height: this.props.height,
@@ -24771,7 +24699,7 @@ class CSProgram extends React__namespace.Component {
24771
24699
  // creator "went wild".
24772
24700
  // http://www.html5rocks.com/en/tutorials/security/sandboxed-iframes/
24773
24701
  return /*#__PURE__*/React__namespace.createElement("div", {
24774
- className: aphrodite.css(styles$p.widthOverride, styleContainer && styles$p.container)
24702
+ className: aphrodite.css(styles$q.widthOverride, styleContainer && styles$q.container)
24775
24703
  }, /*#__PURE__*/React__namespace.createElement("iframe", {
24776
24704
  sandbox: sandboxOptions,
24777
24705
  src: url,
@@ -24781,7 +24709,7 @@ class CSProgram extends React__namespace.Component {
24781
24709
  }));
24782
24710
  }
24783
24711
  }
24784
- const styles$p = aphrodite.StyleSheet.create({
24712
+ const styles$q = aphrodite.StyleSheet.create({
24785
24713
  // Override the inherited width from the perseus paragraph class
24786
24714
  // 820 is minimum width for 420px editor and 400px canvas
24787
24715
  widthOverride: {
@@ -24829,7 +24757,7 @@ class Definition extends React__namespace.Component {
24829
24757
  return /*#__PURE__*/React__namespace.createElement(wonderBlocksPopover.Popover, {
24830
24758
  content: /*#__PURE__*/React__namespace.createElement(wonderBlocksPopover.PopoverContentCore, {
24831
24759
  color: "white",
24832
- style: styles$o.tooltipBody,
24760
+ style: styles$p.tooltipBody,
24833
24761
  closeButtonVisible: true
24834
24762
  }, /*#__PURE__*/React__namespace.createElement(Renderer, {
24835
24763
  apiOptions: this.props.apiOptions,
@@ -24860,7 +24788,7 @@ class Definition extends React__namespace.Component {
24860
24788
  });
24861
24789
  }
24862
24790
  }
24863
- const styles$o = {
24791
+ const styles$p = {
24864
24792
  tooltipBody: {
24865
24793
  color: Color__default["default"].offBlack,
24866
24794
  fontSize: 20,
@@ -25064,15 +24992,15 @@ class Explanation extends React__namespace.Component {
25064
24992
  const onClick = this._onClick;
25065
24993
  if (isMobile) {
25066
24994
  linkContainer = /*#__PURE__*/React__namespace.createElement("div", {
25067
- className: aphrodite.css(styles$n.linkContainer)
24995
+ className: aphrodite.css(styles$o.linkContainer)
25068
24996
  }, /*#__PURE__*/React__namespace.createElement("a", {
25069
- className: aphrodite.css(styles$n.mobileExplanationLink),
24997
+ className: aphrodite.css(styles$o.mobileExplanationLink),
25070
24998
  href: href,
25071
24999
  onClick: onClick,
25072
25000
  role: "button",
25073
25001
  "aria-expanded": this.state.expanded
25074
25002
  }, linkAnchor), this.state.expanded && /*#__PURE__*/React__namespace.createElement("svg", {
25075
- className: aphrodite.css(styles$n.disclosureArrow)
25003
+ className: aphrodite.css(styles$o.disclosureArrow)
25076
25004
  }, /*#__PURE__*/React__namespace.createElement("polygon", {
25077
25005
  style: {
25078
25006
  fill: backgroundColor
@@ -25085,13 +25013,13 @@ class Explanation extends React__namespace.Component {
25085
25013
  // an anchor tag (if rendered in a modal) or a Wonder Blocks
25086
25014
  // link component in lesson page, see: `article-page.jsx`.
25087
25015
  linkContainer = /*#__PURE__*/React__namespace.createElement("div", {
25088
- className: aphrodite.css(styles$n.linkContainer, styles$n.articleLink)
25016
+ className: aphrodite.css(styles$o.linkContainer, styles$o.articleLink)
25089
25017
  }, /*#__PURE__*/React__namespace.createElement(Link, {
25090
- className: aphrodite.css(styles$n.explanationLink)
25018
+ className: aphrodite.css(styles$o.explanationLink)
25091
25019
  // HACK(michaelpolyak): WB Link doesn't passthrough
25092
25020
  // class name.
25093
25021
  ,
25094
- style: styles$n.explanationLink,
25022
+ style: styles$o.explanationLink,
25095
25023
  href: href,
25096
25024
  onClick: onClick,
25097
25025
  role: "button",
@@ -25101,9 +25029,9 @@ class Explanation extends React__namespace.Component {
25101
25029
  // NOTE: For exercises, the baseElements `Link` is an
25102
25030
  // anchor tag, see: `perseus-api.jsx`.
25103
25031
  linkContainer = /*#__PURE__*/React__namespace.createElement("div", {
25104
- className: aphrodite.css(styles$n.linkContainer, styles$n.exerciseLink)
25032
+ className: aphrodite.css(styles$o.linkContainer, styles$o.exerciseLink)
25105
25033
  }, /*#__PURE__*/React__namespace.createElement(Link, {
25106
- className: aphrodite.css(styles$n.explanationLink),
25034
+ className: aphrodite.css(styles$o.explanationLink),
25107
25035
  href: href,
25108
25036
  onClick: onClick,
25109
25037
  role: "button",
@@ -25111,11 +25039,11 @@ class Explanation extends React__namespace.Component {
25111
25039
  }, `[${linkAnchor}]`));
25112
25040
  }
25113
25041
  }
25114
- const expandedStyle = isMobile ? styles$n.contentExpandedMobile : styles$n.contentExpanded;
25042
+ const expandedStyle = isMobile ? styles$o.contentExpandedMobile : styles$o.contentExpanded;
25115
25043
  return /*#__PURE__*/React__namespace.createElement("div", {
25116
- className: aphrodite.css(styles$n.container)
25044
+ className: aphrodite.css(styles$o.container)
25117
25045
  }, linkContainer, this.state.expanded && /*#__PURE__*/React__namespace.createElement("div", {
25118
- className: aphrodite.css(styles$n.content, isMobile && styles$n.contentMobile, this.state.expanded && expandedStyle)
25046
+ className: aphrodite.css(styles$o.content, isMobile && styles$o.contentMobile, this.state.expanded && expandedStyle)
25119
25047
  // eslint-disable-next-line react/no-string-refs
25120
25048
  ,
25121
25049
  ref: "content"
@@ -25138,7 +25066,7 @@ const verticalContentPadding = 10;
25138
25066
  const arrowWidth = 30;
25139
25067
  const arrowHeight = 14;
25140
25068
  const backgroundColor = gray95;
25141
- const styles$n = aphrodite.StyleSheet.create({
25069
+ const styles$o = aphrodite.StyleSheet.create({
25142
25070
  container: {
25143
25071
  display: "inline",
25144
25072
  position: "relative"
@@ -25244,15 +25172,15 @@ class GradedGroupAnswerBar extends React__namespace.Component {
25244
25172
  onNextQuestion
25245
25173
  } = this.props;
25246
25174
  const answerBarStyle = {
25247
- ...styles$m.answerBar,
25175
+ ...styles$n.answerBar,
25248
25176
  backgroundColor: answerBarState === "CORRECT" ? Color__default["default"].offWhite : "white",
25249
25177
  // Center the "Correct!" message only when there's no next question
25250
25178
  justifyContent: answerBarState === "CORRECT" && !onNextQuestion ? "center" : "space-between"
25251
25179
  };
25252
25180
  const message = answerBarState === "INCORRECT" ? /*#__PURE__*/React__namespace.createElement("span", {
25253
- style: styles$m.text
25181
+ style: styles$n.text
25254
25182
  }, /*#__PURE__*/React__namespace.createElement("span", {
25255
- style: styles$m.tryAgainIcon
25183
+ style: styles$n.tryAgainIcon
25256
25184
  }, /*#__PURE__*/React__namespace.createElement(InlineIcon, iconTryAgain)), /*#__PURE__*/React__namespace.createElement("span", {
25257
25185
  style: {
25258
25186
  marginLeft: 8
@@ -25271,7 +25199,7 @@ class GradedGroupAnswerBar extends React__namespace.Component {
25271
25199
  return /*#__PURE__*/React__namespace.createElement("div", {
25272
25200
  style: answerBarStyle
25273
25201
  }, /*#__PURE__*/React__namespace.createElement("span", {
25274
- style: styles$m.text
25202
+ style: styles$n.text
25275
25203
  }, /*#__PURE__*/React__namespace.createElement("span", {
25276
25204
  style: {
25277
25205
  fontSize: 28,
@@ -25293,7 +25221,7 @@ class GradedGroupAnswerBar extends React__namespace.Component {
25293
25221
  }
25294
25222
  }
25295
25223
  const fontSize = 17;
25296
- const styles$m = {
25224
+ const styles$n = {
25297
25225
  answerBar: {
25298
25226
  display: "flex",
25299
25227
  alignItems: "center",
@@ -25493,7 +25421,7 @@ class GradedGroup extends React__namespace.Component {
25493
25421
  // @ts-expect-error - TS2322 - Type 'string' is not assignable to type 'null'.
25494
25422
  gradeStatus = i18n__namespace._("Incorrect");
25495
25423
  }
25496
- const mobileClass = this.props.inGradedGroupSet ? aphrodite.css(styles$l.gradedGroupInSet) : aphrodite.css(styles$l.gradedGroup);
25424
+ const mobileClass = this.props.inGradedGroupSet ? aphrodite.css(styles$m.gradedGroupInSet) : aphrodite.css(styles$m.gradedGroup);
25497
25425
  const classes = classNames__default["default"]({
25498
25426
  [mobileClass]: apiOptions.isMobile,
25499
25427
  "perseus-graded-group": true,
@@ -25512,7 +25440,7 @@ class GradedGroup extends React__namespace.Component {
25512
25440
  return /*#__PURE__*/React__namespace.createElement("div", {
25513
25441
  className: classes
25514
25442
  }, !!this.props.title && /*#__PURE__*/React__namespace.createElement("div", {
25515
- className: aphrodite.css(styles$l.title)
25443
+ className: aphrodite.css(styles$m.title)
25516
25444
  }, this.props.title), /*#__PURE__*/React__namespace.createElement(Renderer, _extends({}, this.props, {
25517
25445
  // eslint-disable-next-line react/no-string-refs
25518
25446
  ref: "renderer",
@@ -25545,7 +25473,7 @@ class GradedGroup extends React__namespace.Component {
25545
25473
  }, i18n__namespace._("Next question")), this.props.hint && this.props.hint.content && (this.state.showHint ? /*#__PURE__*/React__namespace.createElement("div", null, /*#__PURE__*/React__namespace.createElement("button", {
25546
25474
  // @ts-expect-error - TS2322 - Type 'string' is not assignable to type 'number | undefined'.
25547
25475
  tabIndex: "0",
25548
- className: aphrodite.css(styles$l.explanationTitle),
25476
+ className: aphrodite.css(styles$m.explanationTitle),
25549
25477
  onClick: () => this.setState({
25550
25478
  showHint: false
25551
25479
  }),
@@ -25577,7 +25505,7 @@ class GradedGroup extends React__namespace.Component {
25577
25505
  showHint: true
25578
25506
  });
25579
25507
  },
25580
- className: aphrodite.css(styles$l.showHintLink)
25508
+ className: aphrodite.css(styles$m.showHintLink)
25581
25509
  }, i18n__namespace._("Explain"))), apiOptions.isMobile && answerBarState !== "HIDDEN" && /*#__PURE__*/React__namespace.createElement(GradedGroupAnswerBar, {
25582
25510
  apiOptions: apiOptions,
25583
25511
  answerBarState: answerBarState,
@@ -25589,7 +25517,7 @@ class GradedGroup extends React__namespace.Component {
25589
25517
  const traverseChildWidgets$3 = function (props, traverseRenderer) {
25590
25518
  return ___default["default"].extend({}, props, traverseRenderer(props));
25591
25519
  };
25592
- const styles$l = aphrodite.StyleSheet.create({
25520
+ const styles$m = aphrodite.StyleSheet.create({
25593
25521
  gradedGroupInSet: {
25594
25522
  // Reset a few desktop-only styles that come from graded-group.less
25595
25523
  marginLeft: 0,
@@ -25659,20 +25587,20 @@ class Indicators extends React__namespace.Component {
25659
25587
  return /*#__PURE__*/React__namespace.createElement("ul", {
25660
25588
  // reduntantly add class name for use in .less files--
25661
25589
  // the styles object key gets hashed
25662
- className: classNames__default["default"](aphrodite.css(styles$k.indicatorContainer), "indicatorContainer")
25590
+ className: classNames__default["default"](aphrodite.css(styles$l.indicatorContainer), "indicatorContainer")
25663
25591
  }, this.props.gradedGroups.map((_ref, i) => {
25664
25592
  let {
25665
25593
  title
25666
25594
  } = _ref;
25667
25595
  return /*#__PURE__*/React__namespace.createElement("li", {
25668
- className: aphrodite.css(styles$k.indicator),
25596
+ className: aphrodite.css(styles$l.indicator),
25669
25597
  key: title
25670
25598
  }, /*#__PURE__*/React__namespace.createElement(Clickable__default["default"], {
25671
25599
  role: "button",
25672
25600
  "aria-label": i18n__namespace._("Skip to %(title)s", {
25673
25601
  title
25674
25602
  }),
25675
- style: styles$k.indicatorButton,
25603
+ style: styles$l.indicatorButton,
25676
25604
  onClick: () => this.props.onChangeCurrentGroup(i),
25677
25605
  onKeyDown: e => this.handleKeyDown(e, i)
25678
25606
  }, _ref2 => {
@@ -25682,9 +25610,9 @@ class Indicators extends React__namespace.Component {
25682
25610
  pressed
25683
25611
  } = _ref2;
25684
25612
  return /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
25685
- style: [styles$k.indicatorDot, (hovered || focused || pressed) && styles$k.indicatorDotFocused]
25613
+ style: [styles$l.indicatorDot, (hovered || focused || pressed) && styles$l.indicatorDotFocused]
25686
25614
  }, i === this.props.currentGroup && /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
25687
- style: styles$k.indicatorDotActive
25615
+ style: styles$l.indicatorDotActive
25688
25616
  }, /*#__PURE__*/React__namespace.createElement("span", {
25689
25617
  className: aphrodite.css(a11y.srOnly)
25690
25618
  }, i18n__namespace._("Current"))));
@@ -25760,7 +25688,7 @@ class GradedGroupSet extends React__namespace.Component {
25760
25688
  } = getDependencies();
25761
25689
  if (JIPT.useJIPT && this.props.gradedGroups.length > 1) {
25762
25690
  return /*#__PURE__*/React__namespace.createElement("div", {
25763
- className: aphrodite.css(styles$k.container)
25691
+ className: aphrodite.css(styles$l.container)
25764
25692
  }, this.props.gradedGroups.map((gradedGroup, i) => {
25765
25693
  return (
25766
25694
  /*#__PURE__*/
@@ -25783,13 +25711,13 @@ class GradedGroupSet extends React__namespace.Component {
25783
25711
  const numGroups = this.props.gradedGroups.length;
25784
25712
  const handleNextQuestion = this.state.currentGroup < numGroups - 1 ? this.handleNextQuestion : null;
25785
25713
  return /*#__PURE__*/React__namespace.createElement("div", {
25786
- className: aphrodite.css(styles$k.container)
25714
+ className: aphrodite.css(styles$l.container)
25787
25715
  }, /*#__PURE__*/React__namespace.createElement("div", {
25788
- className: aphrodite.css(styles$k.top)
25716
+ className: aphrodite.css(styles$l.top)
25789
25717
  }, /*#__PURE__*/React__namespace.createElement("div", {
25790
- className: aphrodite.css(styles$k.title)
25718
+ className: aphrodite.css(styles$l.title)
25791
25719
  }, currentGroup.title), /*#__PURE__*/React__namespace.createElement("div", {
25792
- className: aphrodite.css(styles$k.spacer)
25720
+ className: aphrodite.css(styles$l.spacer)
25793
25721
  }), /*#__PURE__*/React__namespace.createElement(Indicators, {
25794
25722
  currentGroup: this.state.currentGroup,
25795
25723
  gradedGroups: this.props.gradedGroups,
@@ -25827,7 +25755,7 @@ var GradedGroupSet$1 = {
25827
25755
  tracking: "all",
25828
25756
  isLintable: true
25829
25757
  };
25830
- const styles$k = aphrodite.StyleSheet.create({
25758
+ const styles$l = aphrodite.StyleSheet.create({
25831
25759
  top: {
25832
25760
  display: "flex",
25833
25761
  flexDirection: "row"
@@ -25932,7 +25860,7 @@ class ButtonGroup extends React__namespace.Component {
25932
25860
  id: "" + i,
25933
25861
  ref: "button" + i,
25934
25862
  key: "" + i,
25935
- className: aphrodite.css(styles$j.buttonStyle, button.value === value && styles$j.selectedStyle),
25863
+ className: aphrodite.css(styles$k.buttonStyle, button.value === value && styles$k.selectedStyle),
25936
25864
  onClick: () => this.toggleSelect(button.value)
25937
25865
  }, button.content || "" + button.value);
25938
25866
  });
@@ -25945,7 +25873,7 @@ class ButtonGroup extends React__namespace.Component {
25945
25873
  }, buttons);
25946
25874
  }
25947
25875
  }
25948
- const styles$j = aphrodite.StyleSheet.create({
25876
+ const styles$k = aphrodite.StyleSheet.create({
25949
25877
  buttonStyle: {
25950
25878
  backgroundColor: "white",
25951
25879
  border: "1px solid #ccc",
@@ -31215,7 +31143,7 @@ const HideAnswersToggle = props => {
31215
31143
  const switchId = idFactory.get("hide-answers-toggle");
31216
31144
  const labelId = idFactory.get("hide-answers-label");
31217
31145
  return /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
31218
- style: styles$i.switchWrapper
31146
+ style: styles$j.switchWrapper
31219
31147
  }, /*#__PURE__*/React__namespace.createElement(Switch__default["default"], {
31220
31148
  id: switchId,
31221
31149
  checked: props.areAnswersHidden,
@@ -31227,7 +31155,7 @@ const HideAnswersToggle = props => {
31227
31155
  tag: "label"
31228
31156
  }, strings.hideAnswersToggleLabel));
31229
31157
  };
31230
- const styles$i = aphrodite.StyleSheet.create({
31158
+ const styles$j = aphrodite.StyleSheet.create({
31231
31159
  switchWrapper: {
31232
31160
  display: "flex",
31233
31161
  flexDirection: "row",
@@ -31282,14 +31210,14 @@ const AnswerPill = props => {
31282
31210
  id: idFactory.get("perseus-label-image-widget-answer-pill"),
31283
31211
  onClick: correct ? undefined : onClick,
31284
31212
  ref: ref,
31285
- style: [style, popperStyle, styles$h.pill, correct && styles$h.correct, incorrect && styles$h.incorrect, (focused || hovered) && BringToFront]
31213
+ style: [style, popperStyle, styles$i.pill, correct && styles$i.correct, incorrect && styles$i.incorrect, (focused || hovered) && BringToFront]
31286
31214
  }, /*#__PURE__*/React__namespace.createElement(Renderer, {
31287
31215
  content: answerString,
31288
31216
  inline: true
31289
31217
  }));
31290
31218
  });
31291
31219
  };
31292
- const styles$h = aphrodite.StyleSheet.create({
31220
+ const styles$i = aphrodite.StyleSheet.create({
31293
31221
  correct: {
31294
31222
  // WB green darkened by 18%
31295
31223
  backgroundColor: "#00880b"
@@ -31343,25 +31271,25 @@ class Marker extends React__namespace.Component {
31343
31271
  icon: iconNull
31344
31272
  };
31345
31273
  if (showCorrectness) {
31346
- iconStyles = [styles$g.markerGraded, showCorrectness === "correct" ? styles$g.markerCorrect : styles$g.markerIncorrect, isOpen && styles$g.markerSelected];
31274
+ iconStyles = [styles$h.markerGraded, showCorrectness === "correct" ? styles$h.markerCorrect : styles$h.markerIncorrect, isOpen && styles$h.markerSelected];
31347
31275
  args = {
31348
31276
  ...args,
31349
31277
  icon: showCorrectness === "correct" ? iconCheck : iconMinus
31350
31278
  };
31351
31279
  } else if (selectedAnswers && selectedAnswers.length > 0) {
31352
- iconStyles = [styles$g.markerFilled, isOpen && styles$g.markerSelected];
31280
+ iconStyles = [styles$h.markerFilled, isOpen && styles$h.markerSelected];
31353
31281
  } else if (isOpen) {
31354
- iconStyles = [styles$g.markerSelected];
31282
+ iconStyles = [styles$h.markerSelected];
31355
31283
  args = {
31356
31284
  ...args,
31357
31285
  icon: iconChevronDown,
31358
31286
  size: 8
31359
31287
  };
31360
31288
  } else if (showPulsate) {
31361
- iconStyles = [styles$g.markerPulsateBase, shouldReduceMotion() ? showPulsate && styles$g.markerUnfilledPulsateOnce : showPulsate && styles$g.markerUnfilledPulsateInfinite];
31289
+ iconStyles = [styles$h.markerPulsateBase, shouldReduceMotion() ? showPulsate && styles$h.markerUnfilledPulsateOnce : showPulsate && styles$h.markerUnfilledPulsateInfinite];
31362
31290
  }
31363
31291
  return /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
31364
- style: [styles$g.markerIcon, iconStyles],
31292
+ style: [styles$h.markerIcon, iconStyles],
31365
31293
  ref: node => this._icon = node
31366
31294
  }, /*#__PURE__*/React__namespace.createElement(Icon, args));
31367
31295
  }
@@ -31382,7 +31310,7 @@ class Marker extends React__namespace.Component {
31382
31310
  const markerDisabled = showCorrectness === "correct";
31383
31311
  const active = hovered || focused;
31384
31312
  return /*#__PURE__*/React__namespace.createElement(React__namespace.Fragment, null, /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
31385
- style: [styles$g.marker, active && !markerDisabled && styles$g.markerActive]
31313
+ style: [styles$h.marker, active && !markerDisabled && styles$h.markerActive]
31386
31314
  // already translated in: /widgets/graded-group.tsx
31387
31315
  ,
31388
31316
  "aria-label": markerDisabled ? i18n__namespace._("Correct!") : label
@@ -31397,7 +31325,7 @@ class Marker extends React__namespace.Component {
31397
31325
  }));
31398
31326
  }
31399
31327
  }
31400
- const styles$g = aphrodite.StyleSheet.create({
31328
+ const styles$h = aphrodite.StyleSheet.create({
31401
31329
  marker: {
31402
31330
  position: "absolute",
31403
31331
  backgroundColor: Color__default["default"].white,
@@ -31974,13 +31902,13 @@ class LabelImage extends React__namespace.Component {
31974
31902
  const promptString = isMobile ? multipleAnswers ? i18n__namespace._("Tap each dot on the image to select all answers that apply.") : i18n__namespace._("Tap each dot on the image to select an answer.") : multipleAnswers ? i18n__namespace._("Click each dot on the image to select all answers that apply.") : i18n__namespace._("Click each dot on the image to select an answer.");
31975
31903
  const choicesString = i18n__namespace._("Choices:");
31976
31904
  return /*#__PURE__*/React__namespace.createElement("div", {
31977
- className: classNames__default["default"]("perseus-label-image-widget-instructions", aphrodite.css(styles$f.instructions))
31905
+ className: classNames__default["default"]("perseus-label-image-widget-instructions", aphrodite.css(styles$g.instructions))
31978
31906
  }, /*#__PURE__*/React__namespace.createElement("div", {
31979
- className: aphrodite.css(styles$f.instructionsCaption)
31907
+ className: aphrodite.css(styles$g.instructionsCaption)
31980
31908
  }, promptString, " ", !hideChoices && choicesString), !hideChoices && /*#__PURE__*/React__namespace.createElement("div", {
31981
- className: aphrodite.css(styles$f.instructionsChoices)
31909
+ className: aphrodite.css(styles$g.instructionsChoices)
31982
31910
  }, choices.map((choice, index) => /*#__PURE__*/React__namespace.createElement("div", {
31983
- className: aphrodite.css(styles$f.instructionsChoice),
31911
+ className: aphrodite.css(styles$g.instructionsChoice),
31984
31912
  key: index
31985
31913
  }, /*#__PURE__*/React__namespace.createElement(Renderer, {
31986
31914
  content: choice
@@ -31997,20 +31925,20 @@ class LabelImage extends React__namespace.Component {
31997
31925
  activeMarkerIndex
31998
31926
  } = this.state;
31999
31927
  return /*#__PURE__*/React__namespace.createElement("div", null, this.renderInstructions(), /*#__PURE__*/React__namespace.createElement("div", {
32000
- className: aphrodite.css(styles$f.markersCanvas),
31928
+ className: aphrodite.css(styles$g.markersCanvas),
32001
31929
  style: {
32002
31930
  maxWidth: imageWidth,
32003
31931
  maxHeight: imageHeight
32004
31932
  }
32005
31933
  }, /*#__PURE__*/React__namespace.createElement("div", {
32006
- className: aphrodite.css(styles$f.imageContainer,
31934
+ className: aphrodite.css(styles$g.imageContainer,
32007
31935
  // Ensure image interaction is disabled while answer
32008
31936
  // choices popup is visible. This addresses specific
32009
31937
  // case where user may click on question image to
32010
31938
  // dismiss the popup. If the image is larger in size
32011
31939
  // than its rendered in the widget, this would
32012
31940
  // result in a zoom of the image.
32013
- activeMarkerIndex !== -1 && styles$f.imageInteractionDisabled)
31941
+ activeMarkerIndex !== -1 && styles$g.imageInteractionDisabled)
32014
31942
  }, /*#__PURE__*/React__namespace.createElement(context$1.Consumer, null, _ref3 => {
32015
31943
  let {
32016
31944
  setAssetStatus
@@ -32036,7 +31964,7 @@ class LabelImage extends React__namespace.Component {
32036
31964
  }));
32037
31965
  }
32038
31966
  }
32039
- const styles$f = aphrodite.StyleSheet.create({
31967
+ const styles$g = aphrodite.StyleSheet.create({
32040
31968
  instructions: {
32041
31969
  paddingBottom: 16
32042
31970
  },
@@ -32397,7 +32325,7 @@ class Placeholder extends React__namespace.Component {
32397
32325
  const {
32398
32326
  layout
32399
32327
  } = this.props;
32400
- const className = aphrodite.css(styles$e.card, styles$e.placeholder, layout === Layout.HORIZONTAL && styles$e.horizontalCard);
32328
+ const className = aphrodite.css(styles$f.card, styles$f.placeholder, layout === Layout.HORIZONTAL && styles$f.horizontalCard);
32401
32329
  const style = {
32402
32330
  width: this.props.width,
32403
32331
  height: this.props.height
@@ -32495,7 +32423,7 @@ class Draggable extends React__namespace.Component {
32495
32423
  // We need to keep backwards compatbility with rules specified directly
32496
32424
  // in CSS. Hence the hacky tacking on of manual classNames.
32497
32425
  // See sortable.less for details.
32498
- let className = aphrodite.css(styles$e.card, styles$e.draggable, layout === Layout.HORIZONTAL && styles$e.horizontalCard, layout === Layout.VERTICAL && styles$e.verticalCard, type === ItemState.DRAGGING && styles$e.dragging, type === ItemState.DISABLED && styles$e.disabled, !includePadding && styles$e.unpaddedCard) + " " + ClassNames.INTERACTIVE + " perseus-sortable-draggable";
32426
+ let className = aphrodite.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";
32499
32427
  if (!includePadding) {
32500
32428
  className += " perseus-sortable-draggable-unpadded";
32501
32429
  }
@@ -32795,7 +32723,7 @@ class Sortable extends React__namespace.Component {
32795
32723
  } = this.props;
32796
32724
  // We need to keep backwards compatbility with rules specified directly
32797
32725
  // in CSS. See sortable.less for details.
32798
- const className = aphrodite.css(styles$e.sortable) + " perseus-sortable";
32726
+ const className = aphrodite.css(styles$f.sortable) + " perseus-sortable";
32799
32727
  const syncWidth = this.props.constraints?.width || layout === Layout.VERTICAL;
32800
32728
  const syncHeight = this.props.constraints?.height || layout === Layout.HORIZONTAL;
32801
32729
  ___default["default"].each(this.state.items, function (item, i, items) {
@@ -33026,7 +32954,7 @@ class Sortable extends React__namespace.Component {
33026
32954
  return ___default["default"].pluck(this.state.items, "option");
33027
32955
  }
33028
32956
  }
33029
- const styles$e = aphrodite.StyleSheet.create({
32957
+ const styles$f = aphrodite.StyleSheet.create({
33030
32958
  sortable: {
33031
32959
  boxSizing: "border-box",
33032
32960
  float: "left",
@@ -33154,23 +33082,23 @@ class Matcher extends React__namespace.Component {
33154
33082
  };
33155
33083
  const cellMarginPx = this.props.apiOptions.isMobile ? 8 : 5;
33156
33084
  return /*#__PURE__*/React__namespace.createElement("table", {
33157
- className: aphrodite.css(styles$d.widget) + " " + HACKY_CSS_CLASSNAME
33085
+ className: aphrodite.css(styles$e.widget) + " " + HACKY_CSS_CLASSNAME
33158
33086
  }, /*#__PURE__*/React__namespace.createElement("tbody", null, showLabels && /*#__PURE__*/React__namespace.createElement("tr", {
33159
- className: aphrodite.css(styles$d.row)
33087
+ className: aphrodite.css(styles$e.row)
33160
33088
  }, /*#__PURE__*/React__namespace.createElement("th", {
33161
- className: aphrodite.css(styles$d.column, styles$d.columnLabel)
33089
+ className: aphrodite.css(styles$e.column, styles$e.columnLabel)
33162
33090
  }, /*#__PURE__*/React__namespace.createElement(Renderer, {
33163
33091
  content: this.props.labels[0] || "...",
33164
33092
  linterContext: this.props.linterContext
33165
33093
  })), /*#__PURE__*/React__namespace.createElement("th", {
33166
- className: aphrodite.css(styles$d.column, styles$d.columnRight, styles$d.columnLabel)
33094
+ className: aphrodite.css(styles$e.column, styles$e.columnRight, styles$e.columnLabel)
33167
33095
  }, /*#__PURE__*/React__namespace.createElement(Renderer, {
33168
33096
  content: this.props.labels[1] || "...",
33169
33097
  linterContext: this.props.linterContext
33170
33098
  }))), /*#__PURE__*/React__namespace.createElement("tr", {
33171
- className: aphrodite.css(styles$d.row)
33099
+ className: aphrodite.css(styles$e.row)
33172
33100
  }, /*#__PURE__*/React__namespace.createElement("td", {
33173
- className: aphrodite.css(styles$d.column)
33101
+ className: aphrodite.css(styles$e.column)
33174
33102
  }, /*#__PURE__*/React__namespace.createElement(Sortable, {
33175
33103
  options: left,
33176
33104
  layout: Layout.VERTICAL,
@@ -33185,7 +33113,7 @@ class Matcher extends React__namespace.Component {
33185
33113
  ,
33186
33114
  ref: "left"
33187
33115
  })), /*#__PURE__*/React__namespace.createElement("td", {
33188
- className: aphrodite.css(styles$d.column, styles$d.columnRight)
33116
+ className: aphrodite.css(styles$e.column, styles$e.columnRight)
33189
33117
  }, /*#__PURE__*/React__namespace.createElement(Sortable
33190
33118
  // @ts-expect-error - TS2322 - Type 'readonly unknown[]' is not assignable to type 'readonly string[]'.
33191
33119
  , {
@@ -33271,7 +33199,7 @@ ___default["default"].extend(Matcher, {
33271
33199
  });
33272
33200
  const padding = 5;
33273
33201
  const border = "1px solid #444";
33274
- const styles$d = aphrodite.StyleSheet.create({
33202
+ const styles$e = aphrodite.StyleSheet.create({
33275
33203
  widget: {
33276
33204
  paddingTop: padding,
33277
33205
  maxWidth: "100%",
@@ -34144,9 +34072,9 @@ function drawText(ctx, item) {
34144
34072
  if (item.value === null) {
34145
34073
  return;
34146
34074
  }
34147
- ctx.fillStyle = styles$c.fgColor;
34148
- ctx.font = styles$c.font;
34149
- ctx.fillText(item.value, item.pos[0] - styles$c.fontSizePx / 2 + 1, item.pos[1] + styles$c.fontSizePx / 2);
34075
+ ctx.fillStyle = styles$d.fgColor;
34076
+ ctx.font = styles$d.font;
34077
+ ctx.fillText(item.value, item.pos[0] - styles$d.fontSizePx / 2 + 1, item.pos[1] + styles$d.fontSizePx / 2);
34150
34078
  }
34151
34079
 
34152
34080
  /**
@@ -34167,16 +34095,16 @@ function drawText(ctx, item) {
34167
34095
  function drawDoubleLine(ctx, item) {
34168
34096
  // Outer line that forms both of the bond lines.
34169
34097
  let path = new Path2D();
34170
- ctx.lineWidth = 5 * styles$c.lineWidth;
34171
- ctx.strokeStyle = styles$c.fgColor;
34098
+ ctx.lineWidth = 5 * styles$d.lineWidth;
34099
+ ctx.strokeStyle = styles$d.fgColor;
34172
34100
  path.moveTo(item.startPos[0], item.startPos[1]);
34173
34101
  path.lineTo(item.endPos[0], item.endPos[1]);
34174
34102
  ctx.stroke(path);
34175
34103
 
34176
34104
  // Inner white line that separates the two bond lines.
34177
34105
  path = new Path2D();
34178
- ctx.lineWidth = 3 * styles$c.lineWidth;
34179
- ctx.strokeStyle = styles$c.bgColor;
34106
+ ctx.lineWidth = 3 * styles$d.lineWidth;
34107
+ ctx.strokeStyle = styles$d.bgColor;
34180
34108
  path.moveTo(item.startPos[0], item.startPos[1]);
34181
34109
  path.lineTo(item.endPos[0], item.endPos[1]);
34182
34110
  ctx.stroke(path);
@@ -34203,16 +34131,16 @@ function drawTripleLine(ctx, item) {
34203
34131
 
34204
34132
  // Outer line that will form the two outer bond lines.
34205
34133
  let path = new Path2D();
34206
- ctx.lineWidth = 7 * styles$c.lineWidth;
34207
- ctx.strokeStyle = styles$c.fgColor;
34134
+ ctx.lineWidth = 7 * styles$d.lineWidth;
34135
+ ctx.strokeStyle = styles$d.fgColor;
34208
34136
  path.moveTo(item.startPos[0], item.startPos[1]);
34209
34137
  path.lineTo(item.endPos[0], item.endPos[1]);
34210
34138
  ctx.stroke(path);
34211
34139
 
34212
34140
  // Middle white line that separates the bonds
34213
34141
  path = new Path2D();
34214
- ctx.lineWidth = 5 * styles$c.lineWidth;
34215
- ctx.strokeStyle = styles$c.bgColor;
34142
+ ctx.lineWidth = 5 * styles$d.lineWidth;
34143
+ ctx.strokeStyle = styles$d.bgColor;
34216
34144
  path.moveTo(item.startPos[0], item.startPos[1]);
34217
34145
  path.lineTo(item.endPos[0], item.endPos[1]);
34218
34146
  ctx.stroke(path);
@@ -34234,8 +34162,8 @@ function drawTripleLine(ctx, item) {
34234
34162
  */
34235
34163
  function drawLine(ctx, item) {
34236
34164
  const path = new Path2D();
34237
- ctx.lineWidth = styles$c.lineWidth;
34238
- ctx.strokeStyle = styles$c.fgColor;
34165
+ ctx.lineWidth = styles$d.lineWidth;
34166
+ ctx.strokeStyle = styles$d.fgColor;
34239
34167
  path.moveTo(item.startPos[0], item.startPos[1]);
34240
34168
  path.lineTo(item.endPos[0], item.endPos[1]);
34241
34169
  ctx.stroke(path);
@@ -34287,7 +34215,7 @@ function compareElements(item0, item1) {
34287
34215
  function draw(ctx, items) {
34288
34216
  items.sort(compareElements).forEach(drawItem(ctx));
34289
34217
  }
34290
- const styles$c = {
34218
+ const styles$d = {
34291
34219
  bgColor: "rgb(255, 255, 255)",
34292
34220
  fgColor: "rgb(0, 0, 0)",
34293
34221
  fontSizePx: 12,
@@ -36851,7 +36779,7 @@ class HighlightRenderer extends React__namespace.PureComponent {
36851
36779
  const rects = this.state.cachedHighlightRects;
36852
36780
  return /*#__PURE__*/React__namespace.createElement("div", null, rects.map((rect, index) => /*#__PURE__*/React__namespace.createElement("div", {
36853
36781
  key: index,
36854
- className: aphrodite.css(styles$b.highlightRect),
36782
+ className: aphrodite.css(styles$c.highlightRect),
36855
36783
  style: {
36856
36784
  // NOTE(mdr): We apply `position: absolute` here
36857
36785
  // rather than in Aphrodite styles, because
@@ -36870,7 +36798,7 @@ class HighlightRenderer extends React__namespace.PureComponent {
36870
36798
  })));
36871
36799
  }
36872
36800
  }
36873
- const styles$b = aphrodite.StyleSheet.create({
36801
+ const styles$c = aphrodite.StyleSheet.create({
36874
36802
  highlightRect: {
36875
36803
  background: "#fffabe" // highlighter yellow :)
36876
36804
  }
@@ -36951,7 +36879,7 @@ class HighlightTooltip extends React__namespace.PureComponent {
36951
36879
  // TooltipContent wouldn't let me overwrite
36952
36880
  // user-select and onClick
36953
36881
  const content = /*#__PURE__*/React__namespace.createElement("div", {
36954
- className: aphrodite.css(styles$a.tooltipLabel),
36882
+ className: aphrodite.css(styles$b.tooltipLabel),
36955
36883
  onClick: this.props.onClick
36956
36884
  }, this.props.label);
36957
36885
  const style = {
@@ -36971,7 +36899,7 @@ class HighlightTooltip extends React__namespace.PureComponent {
36971
36899
  }, /*#__PURE__*/React__namespace.createElement("div", null)));
36972
36900
  }
36973
36901
  }
36974
- const styles$a = aphrodite.StyleSheet.create({
36902
+ const styles$b = aphrodite.StyleSheet.create({
36975
36903
  tooltipLabel: {
36976
36904
  // Unlike most tooltip contents, we don't want this label to be
36977
36905
  // selectable. Selecting it is not only unhelpful, but dangerous: if
@@ -37529,7 +37457,7 @@ class HighlightableContent extends React__namespace.PureComponent {
37529
37457
  // starting point: https://phabricator.khanacademy.org/D35623?id=170698
37530
37458
  const buildHighlight = r => this._buildHighlight(r);
37531
37459
  return /*#__PURE__*/React__namespace.createElement("div", {
37532
- className: aphrodite.css(styles$9.container),
37460
+ className: aphrodite.css(styles$a.container),
37533
37461
  ref: container => this._container = container
37534
37462
  }, /*#__PURE__*/React__namespace.createElement("div", null, this.props.enabled && this._container && this._content && /*#__PURE__*/React__namespace.createElement(HighlightingUI, {
37535
37463
  buildHighlight: buildHighlight,
@@ -37550,14 +37478,14 @@ class HighlightableContent extends React__namespace.PureComponent {
37550
37478
  onAddHighlight: this._handleAddHighlight,
37551
37479
  onRemoveHighlight: this._handleRemoveHighlight
37552
37480
  })), /*#__PURE__*/React__namespace.createElement("div", {
37553
- className: aphrodite.css(styles$9.content),
37481
+ className: aphrodite.css(styles$a.content),
37554
37482
  ref: content => this._content = content
37555
37483
  }, /*#__PURE__*/React__namespace.createElement(WordIndexer, {
37556
37484
  onWordsUpdate: this._handleWordsUpdate
37557
37485
  }, this.props.children)));
37558
37486
  }
37559
37487
  }
37560
- const styles$9 = aphrodite.StyleSheet.create({
37488
+ const styles$a = aphrodite.StyleSheet.create({
37561
37489
  // We render content with z-index 1, and highlights with z-index 0, so that
37562
37490
  // content will receive the browser's native pointer events. (Highlights
37563
37491
  // have their own magic code to manage hover detection, despite being
@@ -37953,7 +37881,7 @@ class LineHeightMeasurer extends React__namespace.Component {
37953
37881
  }
37954
37882
  render() {
37955
37883
  return /*#__PURE__*/React__namespace.createElement("div", {
37956
- className: aphrodite.css(styles$8.measurer),
37884
+ className: aphrodite.css(styles$9.measurer),
37957
37885
  "aria-hidden": "true"
37958
37886
  }, /*#__PURE__*/React__namespace.createElement("div", {
37959
37887
  ref: ref => this._line = ref,
@@ -37961,7 +37889,7 @@ class LineHeightMeasurer extends React__namespace.Component {
37961
37889
  }, "Line Height Measurement"));
37962
37890
  }
37963
37891
  }
37964
- const styles$8 = aphrodite.StyleSheet.create({
37892
+ const styles$9 = aphrodite.StyleSheet.create({
37965
37893
  measurer: {
37966
37894
  position: "absolute",
37967
37895
  top: 0,
@@ -39248,6 +39176,52 @@ var Plotter$1 = {
39248
39176
  staticTransform: staticTransform
39249
39177
  };
39250
39178
 
39179
+ /**
39180
+ * This widget is for embedding Khan Academy Python programs.
39181
+ */
39182
+ function getUrlFromProgramID(programID) {
39183
+ const path = `/python-program/${programID}/embedded`;
39184
+ return toAbsoluteUrl(path);
39185
+ }
39186
+ /* This renders the program in an iframe. */
39187
+ class PythonProgram extends React__namespace.Component {
39188
+ static defaultProps = {
39189
+ height: 400
39190
+ };
39191
+ render() {
39192
+ const url = getUrlFromProgramID(this.props.programID);
39193
+ const iframeStyle = {
39194
+ height: this.props.height,
39195
+ width: "100%"
39196
+ };
39197
+ const sandboxOptions = ["allow-popups", "allow-same-origin", "allow-scripts", "allow-top-navigation"].join(" ");
39198
+
39199
+ // We sandbox the iframe so that we allowlist only the functionality
39200
+ // that we need. This makes it a bit safer in case some content
39201
+ // creator "went wild".
39202
+ // http://www.html5rocks.com/en/tutorials/security/sandboxed-iframes/
39203
+ return /*#__PURE__*/React__namespace.createElement(wonderBlocksCore.View, {
39204
+ style: styles$8.container
39205
+ }, /*#__PURE__*/React__namespace.createElement("iframe", {
39206
+ sandbox: sandboxOptions,
39207
+ src: url,
39208
+ style: iframeStyle,
39209
+ allowFullScreen: true
39210
+ }));
39211
+ }
39212
+ }
39213
+ const styles$8 = aphrodite.StyleSheet.create({
39214
+ container: {
39215
+ margin: "auto",
39216
+ width: "100%"
39217
+ }
39218
+ });
39219
+ var PythonProgram$1 = {
39220
+ name: "python-program",
39221
+ displayName: "Python Program",
39222
+ widget: PythonProgram
39223
+ };
39224
+
39251
39225
  class Separator extends React__namespace.Component {
39252
39226
  arrowLength = 100;
39253
39227
  static propTypes = {
@@ -41682,7 +41656,7 @@ var Video$1 = {
41682
41656
  };
41683
41657
 
41684
41658
  /* eslint-disable import/no-named-as-default */
41685
- 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];
41659
+ 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];
41686
41660
 
41687
41661
  /**
41688
41662
  * This should be called by all clients, specifying whether extra widgets are
@@ -41722,7 +41696,7 @@ const init = function (options) {
41722
41696
 
41723
41697
  // This file is processed by a Rollup plugin (replace) to inject the production
41724
41698
  const libName = "@khanacademy/perseus";
41725
- const libVersion = "19.1.9";
41699
+ const libVersion = "19.2.0";
41726
41700
  perseusCore.addLibraryVersionToPerseusDebug(libName, libVersion);
41727
41701
 
41728
41702
  const apiVersion = {
@@ -43167,6 +43141,8 @@ const ItemExtras = [
43167
43141
 
43168
43142
  // prettier-ignore
43169
43143
 
43144
+ // prettier-ignore
43145
+
43170
43146
  //prettier-ignore
43171
43147
 
43172
43148
  // A background image applied to various widgets.