@khanacademy/perseus 39.0.1 → 40.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/es/index.js CHANGED
@@ -6,9 +6,9 @@ import { View, RenderStateRoot, UniqueIDProvider, useOnMountEffect, useLatestRef
6
6
  import Tooltip$1 from '@khanacademy/wonder-blocks-tooltip';
7
7
  import { HeadingMedium, LabelSmall, Body, LabelMedium } from '@khanacademy/wonder-blocks-typography';
8
8
  import { StyleSheet, css } from 'aphrodite';
9
- import classNames from 'classnames';
9
+ import classNames$1 from 'classnames';
10
10
  import * as React from 'react';
11
- import React__default, { useContext, useState, useEffect, useRef, createContext, forwardRef, useImperativeHandle } from 'react';
11
+ import React__default, { useContext, useState, useEffect, useRef, createContext, forwardRef, useLayoutEffect, useImperativeHandle } from 'react';
12
12
  import * as ReactDOM from 'react-dom';
13
13
  import ReactDOM__default from 'react-dom';
14
14
  import _, { debounce as debounce$1 } from 'underscore';
@@ -479,7 +479,7 @@ class InnerMathInput extends React.Component {
479
479
  });
480
480
  }
481
481
  render() {
482
- let className = classNames({
482
+ let className = classNames$1({
483
483
  "perseus-math-input": true,
484
484
  // mathquill usually adds these itself but react removes them when
485
485
  // updating the component.
@@ -2437,7 +2437,7 @@ class Expression extends React.Component {
2437
2437
  onBlur: this._handleBlur
2438
2438
  }));
2439
2439
  }
2440
- const className = classNames({
2440
+ const className = classNames$1({
2441
2441
  "perseus-widget-expression": true,
2442
2442
  "show-error-tooltip": this.state.showErrorTooltip
2443
2443
  });
@@ -3886,12 +3886,12 @@ Zoom.prototype.dispose = function () {
3886
3886
  const ZoomService = new ZoomServiceClass();
3887
3887
 
3888
3888
  // @baseFontFamily: "Lato", sans-serif;
3889
- const baseFontFamily$1 = "'Lato', sans-serif";
3889
+ const baseFontFamily = "'Lato', sans-serif";
3890
3890
  // @boldFontFamily: "Lato-Bold", "Lato", sans-serif;
3891
3891
  const boldFontFamily = "'Lato-Bold', 'Lato', sans-serif";
3892
3892
  // @kaGreen: #71b307;
3893
- const kaGreen$1 = "#71B307";
3894
- const white$1 = "#FFFFFF";
3893
+ const kaGreen = "#71B307";
3894
+ const white = "#FFFFFF";
3895
3895
  const gray97 = "#F6F7F7";
3896
3896
  const gray85 = "#D6D8DA";
3897
3897
  const gray76 = "#BABEC2";
@@ -3899,23 +3899,23 @@ const gray68 = "#888D93";
3899
3899
  const gray17 = "#21242c";
3900
3900
 
3901
3901
  // @pure-sm-min: 568px;
3902
- const pureSmMin$2 = "568px";
3902
+ const pureSmMin$1 = "568px";
3903
3903
  // @pure-md-min: 768px;
3904
- const pureMdMin$2 = "768px";
3904
+ const pureMdMin$1 = "768px";
3905
3905
  // @pure-lg-min: 1024px;
3906
- const pureLgMin$2 = "1024px";
3906
+ const pureLgMin$1 = "1024px";
3907
3907
  // @pure-xl-min: 1280px;
3908
- const pureXlMin$2 = "1280px";
3908
+ const pureXlMin$1 = "1280px";
3909
3909
  // @pure-xs-max: (@pure-sm-min - 1);
3910
- const pureXsMax$2 = "567px";
3910
+ const pureXsMax$1 = "567px";
3911
3911
  // @pure-sm-max: (@pure-md-min - 1);
3912
- const pureSmMax$2 = "767px";
3912
+ const pureSmMax$1 = "767px";
3913
3913
  // @pure-md-max: (@pure-lg-min - 1);
3914
- const pureMdMax$2 = "1023px";
3914
+ const pureMdMax$1 = "1023px";
3915
3915
  // @pure-lg-max: (@pure-xl-min - 1);
3916
- const pureLgMax$2 = "1279px";
3916
+ const pureLgMax$1 = "1279px";
3917
3917
  // @tableBackgroundAccent: #f9f9f9; // for striping
3918
- const tableBackgroundAccent$1 = "#F9F9F9";
3918
+ const tableBackgroundAccent = "#F9F9F9";
3919
3919
  // @zIndexAboveScratchpad: @zIndexScratchPad + 1;
3920
3920
  const zIndexAboveScratchpad$1 = 2;
3921
3921
  // @zIndexInteractiveComponent: @zIndexAboveScratchpad + 1;
@@ -3943,26 +3943,26 @@ const checkedColor$1 = "#71B307";
3943
3943
  const articleMaxWidthInPx = 688;
3944
3944
  const articleMaxWidthTableInPx = 512;
3945
3945
 
3946
- var constants$1 = /*#__PURE__*/Object.freeze({
3946
+ var constants = /*#__PURE__*/Object.freeze({
3947
3947
  __proto__: null,
3948
- baseFontFamily: baseFontFamily$1,
3948
+ baseFontFamily: baseFontFamily,
3949
3949
  boldFontFamily: boldFontFamily,
3950
- kaGreen: kaGreen$1,
3951
- white: white$1,
3950
+ kaGreen: kaGreen,
3951
+ white: white,
3952
3952
  gray97: gray97,
3953
3953
  gray85: gray85,
3954
3954
  gray76: gray76,
3955
3955
  gray68: gray68,
3956
3956
  gray17: gray17,
3957
- pureSmMin: pureSmMin$2,
3958
- pureMdMin: pureMdMin$2,
3959
- pureLgMin: pureLgMin$2,
3960
- pureXlMin: pureXlMin$2,
3961
- pureXsMax: pureXsMax$2,
3962
- pureSmMax: pureSmMax$2,
3963
- pureMdMax: pureMdMax$2,
3964
- pureLgMax: pureLgMax$2,
3965
- tableBackgroundAccent: tableBackgroundAccent$1,
3957
+ pureSmMin: pureSmMin$1,
3958
+ pureMdMin: pureMdMin$1,
3959
+ pureLgMin: pureLgMin$1,
3960
+ pureXlMin: pureXlMin$1,
3961
+ pureXsMax: pureXsMax$1,
3962
+ pureSmMax: pureSmMax$1,
3963
+ pureMdMax: pureMdMax$1,
3964
+ pureLgMax: pureLgMax$1,
3965
+ tableBackgroundAccent: tableBackgroundAccent,
3966
3966
  zIndexAboveScratchpad: zIndexAboveScratchpad$1,
3967
3967
  zIndexInteractiveComponent: zIndexInteractiveComponent$1,
3968
3968
  phoneMargin: phoneMargin,
@@ -4080,7 +4080,7 @@ class FixedToResponsive extends React.Component {
4080
4080
  };
4081
4081
 
4082
4082
  // NOTE(jeremy): This depends on styles defined in perseus-renderer.less
4083
- const className = classNames("fixed-to-responsive", this.props.className);
4083
+ const className = classNames$1("fixed-to-responsive", this.props.className);
4084
4084
  const container = /*#__PURE__*/React.createElement("div", {
4085
4085
  className: className,
4086
4086
  style: style
@@ -14853,77 +14853,26 @@ const iconCheck = {
14853
14853
  width: 24,
14854
14854
  height: 24
14855
14855
  };
14856
- const iconCheckMedium = {
14857
- path: "M6.072 10.4l6.175-7.058a1 1 0 1 1 1.506 1.317L6.769 12.64a1 1 0 0 1-1.55-.054L2.203 8.604a1 1 0 1 1 1.594-1.208L6.072 10.4z",
14858
- width: 16,
14859
- height: 16
14860
- };
14861
14856
  const iconChevronDown = {
14862
14857
  path: "M99.669 13.048q0 3.36-2.352 5.712l-41.664 41.664q-2.408 2.408-5.88 2.408t-5.712-2.408l-41.664-41.664q-2.408-2.24-2.408-5.712t2.408-5.88l4.76-4.816q2.52-2.352 5.88-2.352t5.656 2.352l31.136 31.136 31.08-31.136q2.352-2.352 5.712-2.352t5.88 2.352l4.816 4.816q2.352 2.52 2.352 5.88z",
14863
14858
  width: 100,
14864
14859
  height: 63.034
14865
14860
  };
14866
- const iconChevronRight = {
14867
- path: "M62.808 49.728q0 3.36-2.352 5.88l-41.72 41.664q-2.352 2.408-5.768 2.408t-5.768-2.408l-4.872-4.76q-2.352-2.52-2.352-5.88t2.352-5.712l31.08-31.136-31.08-31.024q-2.352-2.52-2.352-5.88t2.352-5.712l4.872-4.76q2.296-2.408 5.768-2.408t5.768 2.408l41.72 41.664q2.352 2.296 2.352 5.656z",
14868
- width: 63.034,
14869
- height: 100
14870
- };
14871
14861
  const iconCircle = {
14872
14862
  path: "M100.035 50.046q.057 13.623-6.669 25.137t-18.24 18.183-25.08 6.669-25.137-6.726q-11.514-6.726-18.183-18.183-6.726-11.571-6.726-25.137t6.726-25.08 18.24-18.24 25.08-6.669q13.566 0 25.08 6.726 11.514 6.669 18.24 18.183t6.669 25.137z",
14873
14863
  width: 100,
14874
14864
  height: 100
14875
14865
  };
14876
- const iconCircleArrowDown = {
14877
- path: "M50.046 83.676q1.767 0 2.907-1.14l29.526-29.526q1.197-1.197 1.197-2.907t-1.197-2.964l-5.928-5.928q-1.197-1.14-2.964-1.14t-2.907 1.14l-12.312 12.312l0-32.661q0-1.71-1.254-2.964t-2.907-1.254l-8.322 0q-1.71 0-2.964 1.254t-1.254 2.964l0 32.661l-12.312-12.312q-1.197-1.254-2.907-1.254t-2.907 1.254l-5.928 5.928q-1.197 1.197-1.197 2.964t1.197 2.907l29.469 29.526q1.197 1.14 2.964 1.14zm49.989-33.63q.057 13.623-6.669 25.137t-18.24 18.183-25.08 6.669-25.137-6.726q-11.514-6.726-18.183-18.183-6.726-11.571-6.726-25.137t6.726-25.08 18.24-18.24 25.08-6.669q13.566 0 25.08 6.726 11.514 6.669 18.24 18.183t6.669 25.137z",
14878
- width: 100,
14879
- height: 100
14880
- };
14881
- const iconCircleArrowUp = {
14882
- path: "M54.207 83.391q1.653 0 2.907-1.254t1.254-2.907l0-32.718l12.312 12.312q1.254 1.254 2.964 1.254t2.907-1.254l5.928-5.928q1.197-1.197 1.14-2.964 0-1.767-1.14-2.907l-29.526-29.526q-1.197-1.14-2.907-1.14t-2.964 1.14l-29.469 29.526q-1.197 1.254-1.197 2.964t1.197 2.907l5.928 5.928q1.197 1.197 2.907 1.197t2.907-1.197l12.312-12.312l0 32.718q0 1.653 1.254 2.907t2.964 1.254l8.322 0zm45.828-33.345q.057 13.623-6.669 25.137t-18.24 18.183-25.08 6.669-25.137-6.726q-11.514-6.726-18.183-18.183-6.726-11.571-6.726-25.137t6.726-25.08 18.24-18.24 25.08-6.669q13.566 0 25.08 6.726 11.514 6.669 18.24 18.183t6.669 25.137z",
14883
- width: 100,
14884
- height: 100
14885
- };
14886
14866
  const iconCircleThin = {
14887
14867
  path: "M50.046 8.322q-8.493 0-16.188 3.306-15.561 6.669-22.173 22.23-3.363 7.695-3.363 16.188t3.306 16.188 8.949 13.281q5.586 5.586 13.281 8.892t16.188 3.306 16.188-3.306 13.281-8.892 8.892-13.281 3.306-16.188-3.306-16.188-8.892-13.281-13.281-8.949q-7.695-3.306-16.188-3.306zm0 91.713q-13.623 0-25.137-6.726t-18.183-18.183q-6.726-11.571-6.726-25.137t6.726-25.08 18.24-18.24 25.08-6.669q13.566 0 25.08 6.726 11.514 6.669 18.24 18.183t6.726 25.137-6.726 25.137-18.24 18.126q-11.514 6.726-25.08 6.726z",
14888
14868
  width: 100,
14889
14869
  height: 99.944
14890
14870
  };
14891
- const iconDesktop = {
14892
- path: "M94.208 52.119l0-43.746q0-.69-.506-1.15t-1.196-.506l-84.088 0q-.69 0-1.196.506t-.506 1.15l0 43.746q0 .69.506 1.196t1.196.506l84.088 0q.69 0 1.196-.506t.506-1.196zm6.716-43.746l0 57.224q0 3.45-2.484 5.934t-5.934 2.484l-28.566 0q0 3.128 2.53 7.774.828 1.61.828 2.622t-1.012 2.07q-1.012 1.012-2.346.966l-26.91 0q-1.38 0-2.392-1.012t-1.012-2.024q0-1.058 1.656-4.14t1.748-6.256l-28.612 0q-3.45 0-5.934-2.484t-2.484-5.934l0-57.224q0-3.45 2.484-5.934t5.934-2.438l84.088 0q3.45 0 5.98 2.438 2.438 2.484 2.438 5.934z",
14893
- width: 100,
14894
- height: 86.648
14895
- };
14896
- const iconDropdownArrow = {
14897
- path: "M9 9.8c0 .5.7 1.7 1.5 2.8 1.5 1.9 1.5 1.9 3 0C15.7 9.7 15.4 9 12 9c-1.6 0-3 .4-3 .8z",
14898
- width: 24,
14899
- height: 24
14900
- };
14901
- const iconExclamationSign = {
14902
- path: "M58.368 81.225l0-12.369q0-.912-.57-1.539t-1.425-.627l-12.54 0q-.855-.057-1.482.627t-.684 1.539l0 12.369q-.057.855.627 1.482t1.539.684l12.54 0q.855 0 1.425-.627t.57-1.539zm1.026-62.871q0-1.596-2.223-1.71l-14.307 0q-2.109 0-2.223 1.71l1.14 40.47q0 .627.627 1.14t1.539.456l12.084 0q.912-.057 1.539-.513t.684-1.083zm-9.348-18.354q13.566 0 25.08 6.726 11.514 6.669 18.24 18.183t6.726 25.137-6.726 25.137-18.24 18.183-25.08 6.669-25.137-6.726q-11.514-6.726-18.183-18.183-6.726-11.571-6.726-25.137t6.726-25.08 18.24-18.24 25.08-6.669z",
14903
- width: 100,
14904
- height: 99.944
14905
- };
14906
- // Grabbed from https://github.com/encharm/Font-Awesome-SVG-PNG
14907
- const iconGear = {
14908
- path: "M1152 896q0-106-75-181t-181-75-181 75-75 181 75 181 181 75 181-75 75-181zm512-109v222q0 12-8 23t-20 13l-185 28q-19 54-39 91 35 50 107 138 10 12 10 25t-9 23q-27 37-99 108t-94 71q-12 0-26-9l-138-108q-44 23-91 38-16 136-29 186-7 28-36 28h-222q-14 0-24.5-8.5t-11.5-21.5l-28-184q-49-16-90-37l-141 107q-10 9-25 9-14 0-25-11-126-114-165-168-7-10-7-23 0-12 8-23 15-21 51-66.5t54-70.5q-27-50-41-99l-183-27q-13-2-21-12.5t-8-23.5v-222q0-12 8-23t19-13l186-28q14-46 39-92-40-57-107-138-10-12-10-24 0-10 9-23 26-36 98.5-107.5t94.5-71.5q13 0 26 10l138 107q44-23 91-38 16-136 29-186 7-28 36-28h222q14 0 24.5 8.5t11.5 21.5l28 184q49 16 90 37l142-107q9-9 24-9 13 0 25 10 129 119 165 170 7 8 7 22 0 12-8 23-15 21-51 66.5t-54 70.5q26 50 41 98l183 28q13 2 21 12.5t8 23.5z",
14909
- width: 1792,
14910
- height: 1792
14911
- };
14912
- const iconMobilePhone = {
14913
- path: "M36.04 89.557q0-2.584-1.836-4.42t-4.42-1.836-4.352 1.836q-1.836 1.836-1.836 4.42t1.836 4.352 4.42 1.836q2.652-.068 4.42-1.836t1.768-4.352zm16.184-12.444l0-54.74q0-1.088-.748-1.768t-1.768-.68l-39.78 0q-1.088 0-1.768.748t-.68 1.7l0 54.74q0 1.02.748 1.768t1.7.68l39.78 0q1.02-.068 1.768-.748t.748-1.7zm-14.892-65.892q0-1.224-1.292-1.292l-12.444 0q-1.224.068-1.224 1.292t1.224 1.224l12.444 0q1.292 0 1.292-1.224zm22.372-1.292l0 79.628q0 3.944-2.992 6.936t-7.004 2.992l-39.78 0q-4.012 0-7.004-2.924-2.924-2.924-2.924-7.004l0-79.628q0-4.012 2.924-6.936t7.004-2.992l39.78 0q4.012-.068 7.004 2.924t2.992 7.004z",
14914
- width: 60.013,
14915
- height: 100
14916
- };
14917
14871
  const iconOk = {
14918
14872
  path: "M37.964 76.048q-2.576 0-4.368-1.792l-31.864-31.864q-1.792-1.792-1.792-4.368t1.792-4.368l8.736-8.68q1.792-1.792 4.368-1.792t4.312 1.792l18.816 18.872 42-42.056q1.792-1.792 4.368-1.792t4.312 1.792l8.736 8.736q1.792 1.792 1.792 4.368t-1.792 4.312l-55.048 55.048q-1.792 1.792-4.368 1.792z",
14919
14873
  width: 100,
14920
14874
  height: 76.637
14921
14875
  };
14922
- const iconPlus = {
14923
- path: "M99.758 43.09l0 13.578q0 2.852-1.984 4.836t-4.836 1.984l-29.45 0l0 29.45q0 2.852-1.984 4.836t-4.836 1.984l-13.578 0q-2.852 0-4.836-1.984t-1.984-4.836l0-29.45l-29.45 0q-2.852 0-4.836-1.984t-1.984-4.836l0-13.578q0-2.852 1.984-4.836t4.836-1.984l29.45 0l0-29.45q0-2.852 1.984-4.836t4.836-1.984l13.578 0q2.852 0 4.836 1.984t1.984 4.836l0 29.45l29.45 0q2.852 0 4.836 1.984t1.984 4.836z",
14924
- width: 100,
14925
- height: 100
14926
- };
14927
14876
  const iconRemove = {
14928
14877
  path: "M100.464 80.808q0 3.404-2.368 5.772l-11.47 11.544q-2.368 2.368-5.772 2.368t-5.698-2.368l-24.864-24.864-24.864 24.864q-2.368 2.368-5.772 2.368t-5.772-2.368l-11.47-11.544q-2.368-2.368-2.368-5.772t2.368-5.698l24.864-24.864-24.864-24.864q-2.368-2.368-2.368-5.772t2.368-5.772l11.47-11.47q2.368-2.368 5.772-2.368t5.772 2.368l24.864 24.864 24.864-24.864q2.294-2.368 5.698-2.368t5.772 2.368l11.47 11.47q2.368 2.368 2.368 5.772t-2.368 5.772l-24.864 24.864 24.864 24.864q2.368 2.294 2.368 5.698z",
14929
14878
  width: 100,
@@ -14939,53 +14888,17 @@ const iconTryAgain = {
14939
14888
  width: 23,
14940
14889
  height: 23
14941
14890
  };
14942
- const iconTablet = {
14943
- path: "M45.322 90.706q0-1.86-1.302-3.224-1.364-1.364-3.224-1.364t-3.224 1.364-1.302 3.224q0 1.86 1.364 3.224 1.302 1.364 3.162 1.302 1.86.062 3.224-1.302t1.302-3.224zm27.218-11.346l0-68.014q0-.93-.682-1.612t-1.55-.682l-58.962 0q-.93 0-1.612.682t-.682 1.612l0 68.014q0 .93.682 1.612t1.612.62l58.962 0q.992-.062 1.612-.682t.62-1.55zm9.114-68.014l0 77.066q0 4.65-3.348 7.998t-7.998 3.348l-58.962 0q-4.65 0-7.998-3.348t-3.348-7.998l0-77.066q0-4.65 3.348-7.998t7.998-3.348l58.962 0q4.65 0 7.998 3.348t3.348 7.998z",
14944
- width: 81.852,
14945
- height: 100
14946
- };
14947
14891
  const iconTrash = {
14948
14892
  path: "M31.293 37.506q2.052 0 2.052 2.109l0 37.506q0 1.995-2.052 2.109l-4.218 0q-.912-.057-1.482-.627t-.57-1.482l0-37.506q0-2.109 2.052-2.109l4.218 0zm18.753 2.109l0 37.506q0 .912-.57 1.482t-1.539.627l-4.161 0q-1.995 0-2.109-2.109l0-37.506q.057-.912.627-1.482t1.482-.627l4.161 0q.969.057 1.539.627t.57 1.482zm14.592-2.109q2.052 0 2.052 2.109l0 37.506q0 1.995-2.052 2.109l-4.161 0q-.969-.057-1.539-.627t-.57-1.482l0-37.506q0-2.109 2.109-2.109l4.161 0zm10.431 49.248l0-61.731l-58.368 0l0 61.731q.057 2.679.969 3.819t1.083 1.14l54.207 0q.171 0 1.14-1.083t.969-3.876zm-43.776-70.11l29.184 0l-3.135-7.581q-.456-.57-1.14-.741l-20.634 0q-.627.114-1.083.741zm-31.293 2.109q0-1.995 2.109-2.109l20.121 0l4.56-10.83q.969-2.394 3.477-4.104 2.565-1.71 5.187-1.71l20.805 0q2.622 0 5.187 1.71t3.477 4.104l4.56 10.83l20.178 0q.912.057 1.482.627t.57 1.482l0 4.161q0 1.995-2.052 2.109l-6.27 0l0 61.731q0 5.415-3.078 9.348t-7.353 3.933l-54.207 0q-4.275 0-7.353-3.819t-3.078-9.177l0-62.016l-6.213 0q-.969 0-1.539-.57t-.57-1.539l0-4.161z",
14949
14893
  width: 91.681,
14950
14894
  height: 100
14951
14895
  };
14952
- const iconUndo = {
14953
- path: "M10,6.6C10,7.2,9.8,8,9.3,9.1c0,0,0,0.1-0.1,0.1S9.2,9.3,9.2,9.4c0,0,0,0.1-0.1,0.1C9,9.6,9,9.6,8.9,9.6 c-0.1,0-0.1,0-0.1-0.1c0,0,0-0.1,0-0.1c0,0,0-0.1,0-0.1s0-0.1,0-0.1c0-0.3,0-0.5,0-0.7c0-0.4,0-0.7-0.1-1C8.6,7.1,8.5,6.9,8.4,6.7S8.2,6.3,8,6.1C7.8,5.9,7.6,5.8,7.4,5.7S6.9,5.5,6.7,5.5S6.1,5.4,5.8,5.4c-0.3,0-0.6,0-1,0H3.6v1.4c0,0.1,0,0.2-0.1,0.3C3.4,7.1,3.3,7.1,3.2,7.1C3.1,7.1,3,7.1,3,7L0.1,4.1C0,4.1,0,4,0,3.9s0-0.2,0.1-0.3L3,0.8C3,0.7,3.1,0.7,3.2,0.7c0.1,0,0.2,0,0.3,0.1C3.5,0.9,3.6,0.9,3.6,1v1.4h1.2c2.6,0,4.3,0.7,4.9,2.2C9.9,5.2,10,5.8,10,6.6z",
14954
- width: 10,
14955
- height: 10
14956
- };
14957
14896
  const iconMinus = {
14958
14897
  path: `M8,13 L16,13 C16.5522847,13 17,12.5522847 17,12 C17,11.4477153 16.5522847,11 16,11 L8,11 C7.44771525,11 7,11.4477153 7,12 C7,12.5522847 7.44771525,13 8,13 Z`,
14959
14898
  width: 24,
14960
14899
  height: 24
14961
14900
  };
14962
14901
 
14963
- var iconPaths = /*#__PURE__*/Object.freeze({
14964
- __proto__: null,
14965
- iconCheck: iconCheck,
14966
- iconCheckMedium: iconCheckMedium,
14967
- iconChevronDown: iconChevronDown,
14968
- iconChevronRight: iconChevronRight,
14969
- iconCircle: iconCircle,
14970
- iconCircleArrowDown: iconCircleArrowDown,
14971
- iconCircleArrowUp: iconCircleArrowUp,
14972
- iconCircleThin: iconCircleThin,
14973
- iconDesktop: iconDesktop,
14974
- iconDropdownArrow: iconDropdownArrow,
14975
- iconExclamationSign: iconExclamationSign,
14976
- iconGear: iconGear,
14977
- iconMobilePhone: iconMobilePhone,
14978
- iconOk: iconOk,
14979
- iconPlus: iconPlus,
14980
- iconRemove: iconRemove,
14981
- iconStar: iconStar,
14982
- iconTryAgain: iconTryAgain,
14983
- iconTablet: iconTablet,
14984
- iconTrash: iconTrash,
14985
- iconUndo: iconUndo,
14986
- iconMinus: iconMinus
14987
- });
14988
-
14989
14902
  /* eslint-disable @babel/no-invalid-this */
14990
14903
  const add$1 = {
14991
14904
  constrain: function () {
@@ -17432,7 +17345,7 @@ class SvgImage extends React.Component {
17432
17345
  // Just use a normal image if a normal image is provided
17433
17346
  if (!Util.isLabeledSVG(imageSrc)) {
17434
17347
  if (responsive) {
17435
- const wrapperClasses = classNames({
17348
+ const wrapperClasses = classNames$1({
17436
17349
  zoomable: (width || 0) > ZOOMABLE_THRESHOLD,
17437
17350
  "svg-image": true
17438
17351
  });
@@ -18222,7 +18135,7 @@ const styles$C = StyleSheet.create({
18222
18135
  },
18223
18136
  ":hover ~ div span[data-lint-inside-table]": {
18224
18137
  backgroundColor: warningColor,
18225
- color: white$1
18138
+ color: white
18226
18139
  }
18227
18140
  },
18228
18141
  // This is how we position the hover target for inline lint.
@@ -18258,7 +18171,7 @@ const styles$C = StyleSheet.create({
18258
18171
  // draw attention to the linty content.
18259
18172
  ":hover ~ span": {
18260
18173
  backgroundColor: warningColor,
18261
- color: white$1
18174
+ color: white
18262
18175
  }
18263
18176
  },
18264
18177
  radioWidgetHoverTarget: {
@@ -18300,7 +18213,7 @@ const styles$C = StyleSheet.create({
18300
18213
  // draw attention to the linty content.
18301
18214
  ":hover ~ span": {
18302
18215
  backgroundColor: warningColor,
18303
- color: white$1
18216
+ color: white
18304
18217
  }
18305
18218
  },
18306
18219
  // This is the class for the lint indicator in the margin.
@@ -18337,10 +18250,10 @@ const styles$C = StyleSheet.create({
18337
18250
  // When it is displayed, it goes on top!
18338
18251
  zIndex: 1000,
18339
18252
  // These styles control what the tooltip looks like
18340
- color: white$1,
18253
+ color: white,
18341
18254
  backgroundColor: gray17,
18342
18255
  opacity: 0.9,
18343
- fontFamily: baseFontFamily$1,
18256
+ fontFamily: baseFontFamily,
18344
18257
  fontSize: "12px",
18345
18258
  lineHeight: "15px",
18346
18259
  width: "320px",
@@ -19342,7 +19255,7 @@ var preprocessTex = (texCode => texCode
19342
19255
 
19343
19256
  const {
19344
19257
  interactiveSizes
19345
- } = constants$1;
19258
+ } = constants;
19346
19259
 
19347
19260
  // Note: these size cutoffs represent content-width cutoffs as specified in
19348
19261
  // http://zpl.io/1mVmvU (broken link - we no longer use Zeplin)
@@ -19375,13 +19288,6 @@ const getInteractiveBoxFromSizeClass = sizeClass => {
19375
19288
  return [interactiveSizes.defaultBoxSize, interactiveSizes.defaultBoxSize];
19376
19289
  };
19377
19290
 
19378
- var sizingUtils = /*#__PURE__*/Object.freeze({
19379
- __proto__: null,
19380
- containerSizeClass: containerSizeClass,
19381
- getClassFromWidth: getClassFromWidth,
19382
- getInteractiveBoxFromSizeClass: getInteractiveBoxFromSizeClass
19383
- });
19384
-
19385
19291
  class WidgetContainer extends React.Component {
19386
19292
  constructor(...args) {
19387
19293
  super(...args);
@@ -19432,7 +19338,7 @@ class WidgetContainer extends React.Component {
19432
19338
  return this.props.shouldHighlight !== nextProps.shouldHighlight || this.props.type !== nextProps.type || this.state.widgetProps !== nextState.widgetProps || this.state.sizeClass !== nextState.sizeClass;
19433
19339
  }
19434
19340
  render() {
19435
- let className = classNames({
19341
+ let className = classNames$1({
19436
19342
  "perseus-widget-container": true,
19437
19343
  "widget-highlight": this.props.shouldHighlight,
19438
19344
  "widget-nohighlight": !this.props.shouldHighlight,
@@ -20025,7 +19931,7 @@ class Renderer extends React.Component {
20025
19931
  if (this.translationIndex != null) {
20026
19932
  className = null;
20027
19933
  } else {
20028
- className = classNames({
19934
+ className = classNames$1({
20029
19935
  "perseus-paragraph-centered": !this._foundTextNodes,
20030
19936
  // There is only one node being rendered,
20031
19937
  // and it's a full-width widget.
@@ -20841,7 +20747,7 @@ class Renderer extends React.Component {
20841
20747
  const markdownContents = this.outputMarkdown(parsedMarkdown, {
20842
20748
  baseElements: apiOptions.baseElements
20843
20749
  });
20844
- const className = classNames({
20750
+ const className = classNames$1({
20845
20751
  [ClassNames.RENDERER]: true,
20846
20752
  [ClassNames.RESPONSIVE_RENDERER]: true,
20847
20753
  [ClassNames.TWO_COLUMN_RENDERER]: this._isTwoColumn
@@ -24577,29 +24483,29 @@ var PassageRef$1 = {
24577
24483
  * });
24578
24484
  */
24579
24485
  const {
24580
- pureXsMax: pureXsMax$1,
24581
- pureSmMin: pureSmMin$1,
24582
- pureSmMax: pureSmMax$1,
24583
- pureMdMin: pureMdMin$1,
24584
- pureMdMax: pureMdMax$1,
24585
- pureLgMin: pureLgMin$1,
24586
- pureLgMax: pureLgMax$1,
24587
- pureXlMin: pureXlMin$1
24588
- } = constants$1;
24486
+ pureXsMax,
24487
+ pureSmMin,
24488
+ pureSmMax,
24489
+ pureMdMin,
24490
+ pureMdMax,
24491
+ pureLgMin,
24492
+ pureLgMax,
24493
+ pureXlMin
24494
+ } = constants;
24589
24495
  var mediaQueries = {
24590
- xs: `@media screen and (max-width: ${pureXsMax$1})`,
24591
- sm: `@media screen and (min-width: ${pureSmMin$1}) and ` + `(max-width: ${pureSmMax$1})`,
24592
- md: `@media screen and (min-width: ${pureMdMin$1}) and ` + `(max-width: ${pureMdMax$1})`,
24593
- lg: `@media screen and (min-width: ${pureLgMin$1}) and ` + `(max-width: ${pureLgMax$1})`,
24594
- xl: `@media screen and (min-width: ${pureXlMin$1})`,
24595
- xsOrSmaller: `@media screen and (max-width: ${pureXsMax$1})`,
24596
- smOrSmaller: `@media screen and (max-width: ${pureSmMax$1})`,
24597
- mdOrSmaller: `@media screen and (max-width: ${pureMdMax$1})`,
24598
- lgOrSmaller: `@media screen and (max-width: ${pureLgMax$1})`,
24599
- smOrLarger: `@media screen and (min-width: ${pureSmMin$1})`,
24600
- mdOrLarger: `@media screen and (min-width: ${pureMdMin$1})`,
24601
- lgOrLarger: `@media screen and (min-width: ${pureLgMin$1})`,
24602
- xlOrLarger: `@media screen and (min-width: ${pureXlMin$1})`
24496
+ xs: `@media screen and (max-width: ${pureXsMax})`,
24497
+ sm: `@media screen and (min-width: ${pureSmMin}) and ` + `(max-width: ${pureSmMax})`,
24498
+ md: `@media screen and (min-width: ${pureMdMin}) and ` + `(max-width: ${pureMdMax})`,
24499
+ lg: `@media screen and (min-width: ${pureLgMin}) and ` + `(max-width: ${pureLgMax})`,
24500
+ xl: `@media screen and (min-width: ${pureXlMin})`,
24501
+ xsOrSmaller: `@media screen and (max-width: ${pureXsMax})`,
24502
+ smOrSmaller: `@media screen and (max-width: ${pureSmMax})`,
24503
+ mdOrSmaller: `@media screen and (max-width: ${pureMdMax})`,
24504
+ lgOrSmaller: `@media screen and (max-width: ${pureLgMax})`,
24505
+ smOrLarger: `@media screen and (min-width: ${pureSmMin})`,
24506
+ mdOrLarger: `@media screen and (min-width: ${pureMdMin})`,
24507
+ lgOrLarger: `@media screen and (min-width: ${pureLgMin})`,
24508
+ xlOrLarger: `@media screen and (min-width: ${pureXlMin})`
24603
24509
  };
24604
24510
 
24605
24511
  const {
@@ -24609,7 +24515,7 @@ const {
24609
24515
  checkedColor,
24610
24516
  circleSize,
24611
24517
  radioMarginWidth
24612
- } = constants$1;
24518
+ } = constants;
24613
24519
  var sharedStyles = StyleSheet.create({
24614
24520
  perseusInteractive: {
24615
24521
  zIndex: zIndexInteractiveComponent,
@@ -24962,7 +24868,7 @@ function getA11yText(letter, checked, correct, crossedOut, showCorrectness, stri
24962
24868
  */
24963
24869
  const FocusRing = function FocusRing({
24964
24870
  visible = true,
24965
- color = kaGreen$1,
24871
+ color = kaGreen,
24966
24872
  multipleSelect = false,
24967
24873
  children
24968
24874
  }) {
@@ -25090,7 +24996,7 @@ function getDynamicStyles(checked, showCorrectness, pressed, multipleSelect, cor
25090
24996
  backgroundColor = "transparent";
25091
24997
  } else if (checked) {
25092
24998
  const bg = showCorrectness && correct ? color.green : color.blue;
25093
- color$1 = white$1;
24999
+ color$1 = white;
25094
25000
  backgroundColor = bg;
25095
25001
  borderColor = bg;
25096
25002
  } else {
@@ -25168,7 +25074,7 @@ const styles$s = StyleSheet.create({
25168
25074
  borderStyle: "solid",
25169
25075
  borderWidth: 2,
25170
25076
  // The default icons have letters in them. Style those letters.
25171
- fontFamily: baseFontFamily$1,
25077
+ fontFamily: baseFontFamily,
25172
25078
  // NOTE(emily): We explicitly set the font weight instead of using the
25173
25079
  // "bold font family" so that characters which fall back to the default
25174
25080
  // font get bolded too.
@@ -25328,8 +25234,8 @@ const Choice = function Choice(props) {
25328
25234
  crossedOut: updatedCrossedOut
25329
25235
  });
25330
25236
  }
25331
- const descriptionClassName = classNames("description", css(styles$q.description));
25332
- const rationaleClassName = classNames("perseus-radio-rationale-content", css(styles$q.rationale));
25237
+ const descriptionClassName = classNames$1("description", css(styles$q.description));
25238
+ const rationaleClassName = classNames$1("perseus-radio-rationale-content", css(styles$q.rationale));
25333
25239
 
25334
25240
  // We want to show the choices as dimmed out when the choices are disabled.
25335
25241
  // However, we don't want to do this when we're in review mode in the
@@ -25679,8 +25585,8 @@ const BaseRadio = function BaseRadio({
25679
25585
  const isMobile = apiOptions.isMobile;
25680
25586
  const firstChoiceHighlighted = choices[0].highlighted;
25681
25587
  const lastChoiceHighlighted = choices[choices.length - 1].highlighted;
25682
- const className = classNames("perseus-widget-radio", !editMode && "perseus-rendered-radio", css(styles$p.radio, styles$p.responsiveRadioContainer, firstChoiceHighlighted && isMobile && styles$p.radioContainerFirstHighlighted, lastChoiceHighlighted && isMobile && styles$p.radioContainerLastHighlighted));
25683
- const instructionsClassName = classNames("instructions", css(styles$p.instructions, isMobile && styles$p.instructionsMobile));
25588
+ const className = classNames$1("perseus-widget-radio", !editMode && "perseus-rendered-radio", css(styles$p.radio, styles$p.responsiveRadioContainer, firstChoiceHighlighted && isMobile && styles$p.radioContainerFirstHighlighted, lastChoiceHighlighted && isMobile && styles$p.radioContainerLastHighlighted));
25589
+ const instructionsClassName = classNames$1("instructions", css(styles$p.instructions, isMobile && styles$p.instructionsMobile));
25684
25590
  const instructions = getInstructionsText(multipleSelect, countChoices, numCorrect, strings);
25685
25591
  const responsiveClassName = css(styles$p.responsiveFieldset);
25686
25592
  const fieldset = /*#__PURE__*/React.createElement("fieldset", {
@@ -25746,7 +25652,7 @@ const BaseRadio = function BaseRadio({
25746
25652
  if (reviewMode && reviewModeRubric) {
25747
25653
  correctnessClass = reviewModeRubric.choices[i].correct ? ClassNames.CORRECT : ClassNames.INCORRECT;
25748
25654
  }
25749
- const className = classNames(aphroditeClassName(choice.checked),
25655
+ const className = classNames$1(aphroditeClassName(choice.checked),
25750
25656
  // TODO(aria): Make test case for these API
25751
25657
  // classNames
25752
25658
  ClassNames.RADIO.OPTION, choice.checked && ClassNames.RADIO.SELECTED, correctnessClass);
@@ -26539,7 +26445,7 @@ class Categorizer extends React.Component {
26539
26445
 
26540
26446
  // TODO(benkomalo): kill CSS-based styling and move everything to
26541
26447
  // aphrodite.
26542
- const extraClassNames = classNames({
26448
+ const extraClassNames = classNames$1({
26543
26449
  "categorizer-container": true,
26544
26450
  "static-mode": this.props.static
26545
26451
  });
@@ -27433,7 +27339,7 @@ class GradedGroup extends React.Component {
27433
27339
  gradeStatus = this.context.strings.incorrect;
27434
27340
  }
27435
27341
  const mobileClass = this.props.inGradedGroupSet ? css(styles$j.gradedGroupInSet) : css(styles$j.gradedGroup);
27436
- const classes = classNames({
27342
+ const classes = classNames$1({
27437
27343
  [mobileClass]: apiOptions.isMobile,
27438
27344
  "perseus-graded-group": true,
27439
27345
  "answer-correct": apiOptions.isMobile ? false : this.state.status === GRADING_STATUSES.correct,
@@ -27548,7 +27454,7 @@ const styles$j = StyleSheet.create({
27548
27454
  gradedGroup: {
27549
27455
  borderTop: `1px solid ${gray76}`,
27550
27456
  borderBottom: `1px solid ${gray76}`,
27551
- backgroundColor: tableBackgroundAccent$1,
27457
+ backgroundColor: tableBackgroundAccent,
27552
27458
  marginLeft: negativePhoneMargin,
27553
27459
  marginRight: negativePhoneMargin,
27554
27460
  paddingBottom: phoneMargin,
@@ -27612,7 +27518,7 @@ class Indicators extends React.Component {
27612
27518
  return /*#__PURE__*/React.createElement("ul", {
27613
27519
  // reduntantly add class name for use in .less files--
27614
27520
  // the styles object key gets hashed
27615
- className: classNames(css(styles$i.indicatorContainer), "indicatorContainer")
27521
+ className: classNames$1(css(styles$i.indicatorContainer), "indicatorContainer")
27616
27522
  }, this.props.gradedGroups.map(({
27617
27523
  title
27618
27524
  }, i) => /*#__PURE__*/React.createElement("li", {
@@ -27827,7 +27733,7 @@ const styles$i = StyleSheet.create({
27827
27733
  container: {
27828
27734
  borderTop: `1px solid ${gray76}`,
27829
27735
  borderBottom: `1px solid ${gray76}`,
27830
- backgroundColor: tableBackgroundAccent$1,
27736
+ backgroundColor: tableBackgroundAccent,
27831
27737
  marginLeft: negativePhoneMargin,
27832
27738
  marginRight: negativePhoneMargin,
27833
27739
  paddingBottom: phoneMargin,
@@ -28435,21 +28341,6 @@ const typeToButton = type => {
28435
28341
  };
28436
28342
  };
28437
28343
 
28438
- var util = /*#__PURE__*/Object.freeze({
28439
- __proto__: null,
28440
- DEFAULT_BACKGROUND_IMAGE: DEFAULT_BACKGROUND_IMAGE,
28441
- allTypes: allTypes,
28442
- functionForType: functionForType,
28443
- getEquationString: getEquationString,
28444
- pointsFromNormalized: pointsFromNormalized,
28445
- maybePointsFromNormalized: maybePointsFromNormalized,
28446
- defaultPlotProps: defaultPlotProps,
28447
- chooseType: chooseType,
28448
- getGridAndSnapSteps: getGridAndSnapSteps,
28449
- DEFAULT_GRAPHER_PROPS: DEFAULT_GRAPHER_PROPS,
28450
- typeToButton: typeToButton
28451
- });
28452
-
28453
28344
  function getCoefficientsByType(data) {
28454
28345
  if (data.type === "exponential" || data.type === "logarithm") {
28455
28346
  const grader = functionForType(data.type);
@@ -29006,7 +28897,7 @@ class Group extends React.Component {
29006
28897
  // TODO(mdr): Widgets inside this Renderer are not discoverable through
29007
28898
  // the parent Renderer's `findWidgets` function.
29008
28899
  return /*#__PURE__*/React.createElement("div", {
29009
- className: classNames({
28900
+ className: classNames$1({
29010
28901
  "perseus-group": true,
29011
28902
  "perseus-group-valid-answer": isValid,
29012
28903
  "perseus-group-invalid-answer": isInvalid
@@ -29274,7 +29165,7 @@ class ImageWidget extends React.Component {
29274
29165
  }
29275
29166
  _title = `**${_title}** `;
29276
29167
  }
29277
- const className = classNames({
29168
+ const className = classNames$1({
29278
29169
  "perseus-image-caption": true,
29279
29170
  "has-title": !!_title
29280
29171
  });
@@ -31013,7 +30904,7 @@ const styles$g = StyleSheet.create({
31013
30904
  fontFamily: boldFontFamily,
31014
30905
  fontSize: "15px",
31015
30906
  lineHeight: "18px",
31016
- color: white$1,
30907
+ color: white,
31017
30908
  userSelect: "none",
31018
30909
  borderWidth: 0 // <button> gives us a border by default
31019
30910
  },
@@ -31335,7 +31226,7 @@ class NumberInput extends React.Component {
31335
31226
  }
31336
31227
  }
31337
31228
  render() {
31338
- let classes = classNames({
31229
+ let classes = classNames$1({
31339
31230
  "number-input": true,
31340
31231
  "invalid-input": !this._checkValidity(this.props.value),
31341
31232
  mini: this.props.size === "mini",
@@ -32094,7 +31985,12 @@ const actions = {
32094
31985
  },
32095
31986
  polygon: {
32096
31987
  movePoint,
32097
- moveAll
31988
+ moveAll,
31989
+ addPoint,
31990
+ removePoint,
31991
+ focusPoint,
31992
+ blurPoint,
31993
+ clickPoint
32098
31994
  },
32099
31995
  quadratic: {
32100
31996
  movePoint
@@ -32238,6 +32134,7 @@ function reinitialize(params) {
32238
32134
  * https://www.w3.org/WAI/WCAG21/Understanding/target-size.html
32239
32135
  */
32240
32136
  const TARGET_SIZE = 44;
32137
+ const REMOVE_BUTTON_ID = "perseus_mafs_remove_button";
32241
32138
 
32242
32139
  // same as pointsFromNormalized in interactive-graph.tsx
32243
32140
  const normalizePoints = (range, step, coordsList, noSnap) => coordsList.map(coords =>
@@ -32268,6 +32165,9 @@ function bound$1({
32268
32165
  const boundingBox = inset(snapStep, range);
32269
32166
  return clampToBox(boundingBox, point);
32270
32167
  }
32168
+ function isUnlimitedGraphState(state) {
32169
+ return state.type === "point" && state.numPoints === "unlimited" || state.type === "polygon" && state.numSides === "unlimited";
32170
+ }
32271
32171
 
32272
32172
  var isProduction = process.env.NODE_ENV === 'production';
32273
32173
  var prefix = 'Invariant failed';
@@ -32441,33 +32341,26 @@ const hitboxSizePx = 48;
32441
32341
  // MovablePointView is a purely presentational component (i.e. it is a pure
32442
32342
  // function with no state or effects) that renders the SVG for a movable point
32443
32343
  // on an interactive graph.
32444
- //
32445
- // It has two modes for managing tabbing / focus: "controlled" (where the caller
32446
- // manages the display of the focus ring, and the point itself cannot be
32447
- // focused) and "uncontrolled" (where the point is focusable, and the browser
32448
- // manages the focus state and styling). For context on why we did this, see
32449
- // the description of https://github.com/Khan/perseus/pull/1240
32450
32344
  const MovablePointView = /*#__PURE__*/forwardRef((props, hitboxRef) => {
32451
32345
  var _Object$entries$find$, _Object$entries$find;
32452
32346
  const {
32453
32347
  range,
32454
32348
  markings,
32455
- showTooltips,
32456
- disableKeyboardInteraction
32349
+ showTooltips
32457
32350
  } = useGraphConfig();
32458
32351
  const {
32459
32352
  point,
32460
32353
  color: color$1 = color.blue,
32461
32354
  dragging,
32462
- focusBehavior,
32463
32355
  cursor,
32356
+ showFocusRing,
32464
32357
  onClick = () => {}
32465
32358
  } = props;
32466
32359
 
32467
32360
  // WB Tooltip requires a color name for the background color.
32468
32361
  // Since the color in props is a hex value, a reverse lookup is needed.
32469
32362
  const wbColorName = (_Object$entries$find$ = (_Object$entries$find = Object.entries(color).find(([_, value]) => value === color$1)) == null ? void 0 : _Object$entries$find[0]) != null ? _Object$entries$find$ : "blue";
32470
- const pointClasses = `movable-point ${dragging ? "movable-point--dragging" : ""} ${focusClass(focusBehavior)}`;
32363
+ const pointClasses = classNames("movable-point", dragging && "movable-point--dragging", showFocusRing && "movable-point--focus");
32471
32364
  const [[x, y]] = useTransformVectorsToPixels(point);
32472
32365
  const [[xMin, xMax], [yMin, yMax]] = range;
32473
32366
  const [[verticalStartX]] = useTransformVectorsToPixels([xMin, 0]);
@@ -32496,15 +32389,6 @@ const MovablePointView = /*#__PURE__*/forwardRef((props, hitboxRef) => {
32496
32389
  cursor
32497
32390
  },
32498
32391
  "data-testid": "movable-point",
32499
- tabIndex: disableKeyboardInteraction ? -1 : tabIndex(focusBehavior),
32500
- onFocus: event => {
32501
- const callback = getOnFocusChangeCallback(focusBehavior);
32502
- callback && callback(event, true);
32503
- },
32504
- onBlur: event => {
32505
- const callback = getOnFocusChangeCallback(focusBehavior);
32506
- callback && callback(event, false);
32507
- },
32508
32392
  onClick: onClick
32509
32393
  }, /*#__PURE__*/React.createElement("circle", {
32510
32394
  className: "movable-point-hitbox",
@@ -32541,25 +32425,100 @@ const MovablePointView = /*#__PURE__*/forwardRef((props, hitboxRef) => {
32541
32425
  }
32542
32426
  }, svgForPoint) : svgForPoint);
32543
32427
  });
32544
- function focusClass(config) {
32545
- if (config.type === "controlled" && config.showFocusRing) {
32546
- return "movable-point--focus";
32547
- }
32548
- return "";
32428
+
32429
+ // TODO(benchristel): Move this to a more central location if it's reused.
32430
+ // Or install the library.
32431
+ function classNames(...names) {
32432
+ return names.filter(Boolean).join(" ");
32549
32433
  }
32550
- function tabIndex(config) {
32551
- if (config.type === "uncontrolled") {
32552
- return config.tabIndex;
32553
- }
32554
- return undefined;
32434
+
32435
+ function useControlPoint(params) {
32436
+ const {
32437
+ snapStep,
32438
+ disableKeyboardInteraction
32439
+ } = useGraphConfig();
32440
+ const {
32441
+ point,
32442
+ color,
32443
+ cursor,
32444
+ constrain = p => snap(snapStep, p),
32445
+ onMove = noop$1,
32446
+ onClick = noop$1,
32447
+ onFocus = noop$1,
32448
+ onBlur = noop$1,
32449
+ forwardedRef = noop$1
32450
+ } = params;
32451
+ const [focused, setFocused] = useState(false);
32452
+ const focusableHandleRef = useRef(null);
32453
+ useDraggable({
32454
+ gestureTarget: focusableHandleRef,
32455
+ point,
32456
+ onMove,
32457
+ constrainKeyboardMovement: constrain
32458
+ });
32459
+ const visiblePointRef = useRef(null);
32460
+ const {
32461
+ dragging
32462
+ } = useDraggable({
32463
+ gestureTarget: visiblePointRef,
32464
+ point,
32465
+ onMove,
32466
+ constrainKeyboardMovement: constrain
32467
+ });
32468
+ useLayoutEffect(() => {
32469
+ setForwardedRef(forwardedRef, focusableHandleRef.current);
32470
+ }, [forwardedRef]);
32471
+ const focusableHandle = /*#__PURE__*/React.createElement("g", {
32472
+ "data-testid": "movable-point__focusable-handle",
32473
+ className: "movable-point__focusable-handle",
32474
+ tabIndex: disableKeyboardInteraction ? -1 : 0,
32475
+ ref: focusableHandleRef,
32476
+ onFocus: event => {
32477
+ onFocus(event);
32478
+ setFocused(true);
32479
+ },
32480
+ onBlur: event => {
32481
+ onBlur(event);
32482
+ setFocused(false);
32483
+ }
32484
+ });
32485
+ const visiblePoint = /*#__PURE__*/React.createElement(MovablePointView, {
32486
+ cursor: cursor,
32487
+ onClick: () => {
32488
+ var _focusableHandleRef$c;
32489
+ onClick();
32490
+ (_focusableHandleRef$c = focusableHandleRef.current) == null || _focusableHandleRef$c.focus();
32491
+ },
32492
+ point: point,
32493
+ dragging: dragging,
32494
+ color: color,
32495
+ ref: visiblePointRef,
32496
+ showFocusRing: focused
32497
+ });
32498
+ return {
32499
+ focusableHandle,
32500
+ visiblePoint,
32501
+ focusableHandleRef,
32502
+ visiblePointRef
32503
+ };
32555
32504
  }
32556
- function getOnFocusChangeCallback(config) {
32557
- if (config.type === "uncontrolled") {
32558
- return config.onFocusChange;
32505
+
32506
+ // TODO(benchristel): move this to a more central place if we want to reuse it.
32507
+ function setForwardedRef(ref, value) {
32508
+ if (typeof ref === "function") {
32509
+ ref(value);
32510
+ } else if (ref !== null) {
32511
+ ref.current = value;
32559
32512
  }
32560
- return () => {};
32561
32513
  }
32562
32514
 
32515
+ // This `noop` const is an optimization. Above, we use the forwardedRef
32516
+ // variable, which defaults to `noop`, in a useEffect deps array. Using `noop`
32517
+ // as the default value instead of `() => {}` ensures that the forwardedRef
32518
+ // variable will have the same value on repeated renders, preventing the
32519
+ // useEffect callback from re-running needlessly.
32520
+ const noop$1 = () => {};
32521
+
32563
32522
  const MovableLine = props => {
32564
32523
  const {
32565
32524
  onMoveLine = () => {},
@@ -32583,11 +32542,19 @@ const MovableLine = props => {
32583
32542
  const {
32584
32543
  visiblePoint: visiblePoint1,
32585
32544
  focusableHandle: focusableHandle1
32586
- } = useControlPoint(start, color, p => onMovePoint(0, p));
32545
+ } = useControlPoint({
32546
+ point: start,
32547
+ color,
32548
+ onMove: p => onMovePoint(0, p)
32549
+ });
32587
32550
  const {
32588
32551
  visiblePoint: visiblePoint2,
32589
32552
  focusableHandle: focusableHandle2
32590
- } = useControlPoint(end, color, p => onMovePoint(1, p));
32553
+ } = useControlPoint({
32554
+ point: end,
32555
+ color,
32556
+ onMove: p => onMovePoint(1, p)
32557
+ });
32591
32558
  const line = /*#__PURE__*/React.createElement(Line$1, {
32592
32559
  start: start,
32593
32560
  end: end,
@@ -32597,51 +32564,6 @@ const MovableLine = props => {
32597
32564
  });
32598
32565
  return /*#__PURE__*/React.createElement(React.Fragment, null, focusableHandle1, line, focusableHandle2, visiblePoint1, visiblePoint2);
32599
32566
  };
32600
- function useControlPoint(point, color, onMovePoint) {
32601
- const {
32602
- snapStep,
32603
- disableKeyboardInteraction
32604
- } = useGraphConfig();
32605
- const [focused, setFocused] = useState(false);
32606
- const keyboardHandleRef = useRef(null);
32607
- useDraggable({
32608
- gestureTarget: keyboardHandleRef,
32609
- point,
32610
- onMove: onMovePoint,
32611
- constrainKeyboardMovement: p => snap(snapStep, p)
32612
- });
32613
- const visiblePointRef = useRef(null);
32614
- const {
32615
- dragging
32616
- } = useDraggable({
32617
- gestureTarget: visiblePointRef,
32618
- point,
32619
- onMove: onMovePoint,
32620
- constrainKeyboardMovement: p => snap(snapStep, p)
32621
- });
32622
- const focusableHandle = /*#__PURE__*/React.createElement("g", {
32623
- "data-testid": "movable-point__focusable-handle",
32624
- className: "movable-point__focusable-handle",
32625
- tabIndex: disableKeyboardInteraction ? -1 : 0,
32626
- ref: keyboardHandleRef,
32627
- onFocus: () => setFocused(true),
32628
- onBlur: () => setFocused(false)
32629
- });
32630
- const visiblePoint = /*#__PURE__*/React.createElement(MovablePointView, {
32631
- point: point,
32632
- dragging: dragging,
32633
- color: color,
32634
- ref: visiblePointRef,
32635
- focusBehavior: {
32636
- type: "controlled",
32637
- showFocusRing: focused
32638
- }
32639
- });
32640
- return {
32641
- focusableHandle,
32642
- visiblePoint
32643
- };
32644
- }
32645
32567
  const defaultStroke = "var(--movable-line-stroke-color)";
32646
32568
  const Line$1 = props => {
32647
32569
  const {
@@ -33143,60 +33065,15 @@ function calculateBisectorPoint(point1, point2, vertex, isReflex, allowReflex, a
33143
33065
 
33144
33066
  const MovablePoint$1 = /*#__PURE__*/React.forwardRef((props, pointRef) => {
33145
33067
  const {
33146
- snapStep
33147
- } = useGraphConfig();
33148
- const elementRef = useRef(null);
33149
- const {
33150
- point,
33151
- onMove = () => {},
33152
- onFocusChange = () => {},
33153
- onClick = () => {},
33154
- cursor,
33155
- color: color$1 = color.blue,
33156
- constrain = p => snap(snapStep, p)
33157
- } = props;
33158
- const {
33159
- dragging
33160
- } = useDraggable({
33161
- gestureTarget: elementRef,
33162
- point,
33163
- onMove,
33164
- constrainKeyboardMovement: constrain
33165
- });
33166
- return /*#__PURE__*/React.createElement(MovablePointView, {
33167
- ref: ref => {
33168
- // Note: This handles the case where pointRef is either a
33169
- // function or a MutableRefObject. Mostly this is to satisfy
33170
- // the type system, the function branch seems to be the only
33171
- // one that occurs
33172
- if (typeof pointRef === "function") {
33173
- pointRef(ref);
33174
- } else if (pointRef !== null) {
33175
- pointRef.current = ref;
33176
- }
33177
-
33178
- // This ref is for the useDraggable and is not passed up the
33179
- // chain
33180
- elementRef.current = ref;
33181
- },
33182
- point: point,
33183
- color: color$1,
33184
- dragging: dragging,
33185
- focusBehavior: {
33186
- type: "uncontrolled",
33187
- tabIndex: 0,
33188
- onFocusChange
33189
- },
33190
- onClick: () => {
33191
- var _elementRef$current;
33192
- onClick && onClick();
33193
- (_elementRef$current = elementRef.current) == null || _elementRef$current.focus();
33194
- },
33195
- cursor: cursor
33196
- });
33068
+ visiblePoint,
33069
+ focusableHandle
33070
+ } = useControlPoint(_extends({}, props, {
33071
+ forwardedRef: pointRef
33072
+ }));
33073
+ return /*#__PURE__*/React.createElement(React.Fragment, null, focusableHandle, visiblePoint);
33197
33074
  });
33198
33075
 
33199
- const PolygonGraph = props => {
33076
+ const LimitedPolygonGraph = props => {
33200
33077
  const [hovered, setHovered] = React.useState(false);
33201
33078
  // This is more so required for the re-rendering that occurs when state
33202
33079
  // updates; specifically with regard to line weighting and polygon focus.
@@ -33307,6 +33184,153 @@ const PolygonGraph = props => {
33307
33184
  }
33308
33185
  })));
33309
33186
  };
33187
+
33188
+ // TODO(catjohnson): reduce redundancy between LimitedPolygonGraph and UnlimitedPolygonGraph
33189
+ // both components are vary similar, however more implementation is needed to be added before
33190
+ // it is clear what can and can't be shared between components.
33191
+ const UnlimitedPolygonGraph = props => {
33192
+ const [hovered, setHovered] = React.useState(false);
33193
+ // This is more so required for the re-rendering that occurs when state
33194
+ // updates; specifically with regard to line weighting and polygon focus.
33195
+ const [focusVisible, setFocusVisible] = React.useState(false);
33196
+ const {
33197
+ dispatch
33198
+ } = props;
33199
+ const {
33200
+ coords,
33201
+ showAngles,
33202
+ showSides,
33203
+ range,
33204
+ snapStep,
33205
+ snapTo = "grid"
33206
+ } = props.graphState;
33207
+ const graphConfig = useGraphConfig();
33208
+
33209
+ // TODO(catjohnson): Explore abstracting this code as it is similar to point.tsx
33210
+ // and hopefully we can cut down ont the unlimited graph redundancy.
33211
+ const {
33212
+ range: [x, y],
33213
+ disableKeyboardInteraction,
33214
+ graphDimensionsInPixels
33215
+ } = graphConfig;
33216
+ const widthPx = graphDimensionsInPixels[0];
33217
+ const heightPx = graphDimensionsInPixels[1];
33218
+ const [[left, top]] = useTransformVectorsToPixels([x[0], y[1]]);
33219
+ const pointRef = React.useRef([]);
33220
+
33221
+ // TODO(benchristel): can the default set of points be removed here? I don't
33222
+ // think coords can be null.
33223
+ const points = coords != null ? coords : [[0, 0]];
33224
+ const polygonRef = React.useRef(null);
33225
+ const dragReferencePoint = points[0];
33226
+ const constrain = ["angles", "sides"].includes(snapTo) ? p => p : p => snap(snapStep, p);
33227
+ const {
33228
+ dragging
33229
+ } = useDraggable({
33230
+ gestureTarget: polygonRef,
33231
+ point: dragReferencePoint,
33232
+ onMove: newPoint => {
33233
+ const delta = vec.sub(newPoint, dragReferencePoint);
33234
+ dispatch(actions.polygon.moveAll(delta));
33235
+ },
33236
+ constrainKeyboardMovement: constrain
33237
+ });
33238
+ const lines = getLines(points);
33239
+ React.useEffect(() => {
33240
+ const focusedIndex = props.graphState.focusedPointIndex;
33241
+ if (focusedIndex != null) {
33242
+ var _pointRef$current$foc;
33243
+ (_pointRef$current$foc = pointRef.current[focusedIndex]) == null || _pointRef$current$foc.focus();
33244
+ }
33245
+ }, [props.graphState.focusedPointIndex, pointRef]);
33246
+ return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("rect", {
33247
+ style: {
33248
+ fill: "rgba(0,0,0,0)",
33249
+ cursor: "crosshair"
33250
+ },
33251
+ width: widthPx,
33252
+ height: heightPx,
33253
+ x: left,
33254
+ y: top,
33255
+ onClick: event => {
33256
+ const elementRect = event.currentTarget.getBoundingClientRect();
33257
+ const x = event.clientX - elementRect.x;
33258
+ const y = event.clientY - elementRect.y;
33259
+ const graphCoordinates = pixelsToVectors([[x, y]], graphConfig);
33260
+ dispatch(actions.polygon.addPoint(graphCoordinates[0]));
33261
+ }
33262
+ }), /*#__PURE__*/React.createElement(Polygon, {
33263
+ points: [...points],
33264
+ color: "var(--movable-line-stroke-color)",
33265
+ svgPolygonProps: {
33266
+ strokeWidth: focusVisible ? "var(--movable-line-stroke-weight-active)" : "var(--movable-line-stroke-weight)",
33267
+ style: {
33268
+ fill: "transparent"
33269
+ }
33270
+ }
33271
+ }), props.graphState.coords.map((point, i) => {
33272
+ const pt1 = points.at(i - 1);
33273
+ const pt2 = points[(i + 1) % points.length];
33274
+ if (!pt1 || !pt2) {
33275
+ return null;
33276
+ }
33277
+ return /*#__PURE__*/React.createElement(PolygonAngle, {
33278
+ key: "angle-" + i,
33279
+ centerPoint: point,
33280
+ endPoints: [pt1, pt2],
33281
+ range: range,
33282
+ polygonLines: lines,
33283
+ showAngles: !!showAngles,
33284
+ snapTo: snapTo
33285
+ });
33286
+ }), showSides && lines.map(([start, end], i) => {
33287
+ const [x, y] = vec.midpoint(start, end);
33288
+ const length = parseFloat(vec.dist(start, end).toFixed(snapTo === "sides" ? 0 : 1));
33289
+ return /*#__PURE__*/React.createElement(TextLabel, {
33290
+ key: "side-" + i,
33291
+ x: x,
33292
+ y: y
33293
+ }, !Number.isInteger(length) && "≈ ", length);
33294
+ }), /*#__PURE__*/React.createElement(Polygon, {
33295
+ points: [...points],
33296
+ color: "transparent",
33297
+ svgPolygonProps: {
33298
+ ref: polygonRef,
33299
+ tabIndex: disableKeyboardInteraction ? -1 : 0,
33300
+ strokeWidth: TARGET_SIZE,
33301
+ style: {
33302
+ cursor: dragging ? "grabbing" : "grab",
33303
+ fill: hovered ? "var(--mafs-blue)" : "transparent"
33304
+ },
33305
+ onMouseEnter: () => setHovered(true),
33306
+ onMouseLeave: () => setHovered(false),
33307
+ // Required to remove line weighting when user clicks away
33308
+ // from the focused polygon
33309
+ onKeyDownCapture: () => {
33310
+ setFocusVisible(hasFocusVisible(polygonRef.current));
33311
+ },
33312
+ // Required for lines to darken on focus
33313
+ onFocus: () => setFocusVisible(hasFocusVisible(polygonRef.current)),
33314
+ // Required for line weighting to update on blur. Without this,
33315
+ // the user has to hover over the shape for it to update
33316
+ onBlur: () => setFocusVisible(hasFocusVisible(polygonRef.current)),
33317
+ className: "movable-polygon"
33318
+ }
33319
+ }), props.graphState.coords.map((point, i) => /*#__PURE__*/React.createElement(MovablePoint$1, {
33320
+ key: i,
33321
+ point: point,
33322
+ onMove: destination => dispatch(actions.pointGraph.movePoint(i, destination)),
33323
+ ref: ref => {
33324
+ pointRef.current[i] = ref;
33325
+ },
33326
+ onFocus: () => {
33327
+ dispatch(actions.pointGraph.focusPoint(i));
33328
+ },
33329
+ onClick: () => {
33330
+ dispatch(actions.pointGraph.clickPoint(i));
33331
+ }
33332
+ })));
33333
+ };
33310
33334
  function getLines(points) {
33311
33335
  return points.map((point, i) => {
33312
33336
  const next = points[(i + 1) % points.length];
@@ -33327,6 +33351,10 @@ const hasFocusVisible = element => {
33327
33351
  return matches(":focus");
33328
33352
  }
33329
33353
  };
33354
+ const PolygonGraph = props => {
33355
+ const numSides = props.graphState.numSides;
33356
+ return numSides === "unlimited" ? UnlimitedPolygonGraph(props) : LimitedPolygonGraph(props);
33357
+ };
33330
33358
 
33331
33359
  function getGradableGraph(state, initialGraph) {
33332
33360
  if (!state.hasBeenInteractedWith) {
@@ -33766,10 +33794,10 @@ function UnlimitedPointGraph(props) {
33766
33794
  const {
33767
33795
  dispatch
33768
33796
  } = props;
33769
- const graphState = useGraphConfig();
33797
+ const graphConfig = useGraphConfig();
33770
33798
  const {
33771
33799
  range: [[minX, maxX], [minY, maxY]]
33772
- } = graphState;
33800
+ } = graphConfig;
33773
33801
  const width = maxX - minX;
33774
33802
  const height = maxY - minY;
33775
33803
  const [[widthPx, heightPx]] = useTransformDimensionsToPixels([width, height]);
@@ -33795,7 +33823,7 @@ function UnlimitedPointGraph(props) {
33795
33823
  const elementRect = event.currentTarget.getBoundingClientRect();
33796
33824
  const x = event.clientX - elementRect.x;
33797
33825
  const y = event.clientY - elementRect.y;
33798
- const graphCoordinates = pixelsToVectors([[x, y]], graphState);
33826
+ const graphCoordinates = pixelsToVectors([[x, y]], graphConfig);
33799
33827
  dispatch(actions.pointGraph.addPoint(graphCoordinates[0]));
33800
33828
  }
33801
33829
  }), props.graphState.coords.map((point, i) => /*#__PURE__*/React.createElement(MovablePoint$1, {
@@ -33805,24 +33833,8 @@ function UnlimitedPointGraph(props) {
33805
33833
  ref: ref => {
33806
33834
  itemsRef.current[i] = ref;
33807
33835
  },
33808
- onFocusChange: (event, isFocused) => {
33809
- if (isFocused) {
33810
- dispatch(actions.pointGraph.focusPoint(i));
33811
- } else {
33812
- var _event$relatedTarget, _event$relatedTarget2;
33813
- if (((_event$relatedTarget = event.relatedTarget) == null ? void 0 : _event$relatedTarget.id) === REMOVE_BUTTON_ID) {
33814
- return;
33815
- // This is an optimization: If the next target
33816
- // is a point then don't blur because it casues
33817
- // the remove button to get taken off the page
33818
- // and then put back on The new point will
33819
- // receive focus and set the correct state in
33820
- // the reducer
33821
- } else if ((_event$relatedTarget2 = event.relatedTarget) != null && _event$relatedTarget2.classList.contains("movable-point")) {
33822
- return;
33823
- }
33824
- dispatch(actions.pointGraph.blurPoint());
33825
- }
33836
+ onFocus: () => {
33837
+ dispatch(actions.pointGraph.focusPoint(i));
33826
33838
  },
33827
33839
  onClick: () => {
33828
33840
  dispatch(actions.pointGraph.clickPoint(i));
@@ -33984,7 +33996,6 @@ function useDraggablePx(args) {
33984
33996
  * - Protractor
33985
33997
  * - Interactive Graph Elements
33986
33998
  */
33987
- const REMOVE_BUTTON_ID = "perseus_mafs_remove_button";
33988
33999
  const MafsGraph = props => {
33989
34000
  var _props$flags;
33990
34001
  const {
@@ -34025,6 +34036,7 @@ const MafsGraph = props => {
34025
34036
  const {
34026
34037
  strings
34027
34038
  } = usePerseusI18n();
34039
+ const interactionPrompt = isUnlimitedGraphState(state) && state.showKeyboardInteractionInvitation;
34028
34040
  useOnMountEffect(() => {
34029
34041
  analytics.onAnalyticsEvent({
34030
34042
  type: "perseus:interactive-graph-widget:rendered",
@@ -34137,7 +34149,7 @@ const MafsGraph = props => {
34137
34149
  }, /*#__PURE__*/React.createElement("svg", nestedSVGAttributes, props.showProtractor && /*#__PURE__*/React.createElement(Protractor, null), renderGraph({
34138
34150
  state,
34139
34151
  dispatch
34140
- }))))), state.type === "point" && state.showKeyboardInteractionInvitation && /*#__PURE__*/React.createElement(View, {
34152
+ }))))), interactionPrompt && /*#__PURE__*/React.createElement(View, {
34141
34153
  style: {
34142
34154
  textAlign: "center",
34143
34155
  backgroundColor: "white",
@@ -34154,7 +34166,7 @@ const MafsGraph = props => {
34154
34166
  state,
34155
34167
  dispatch,
34156
34168
  width,
34157
- strings
34169
+ perseusStrings: strings
34158
34170
  })));
34159
34171
  };
34160
34172
  const renderPointGraphControls = props => {
@@ -34164,7 +34176,7 @@ const renderPointGraphControls = props => {
34164
34176
  focusedPointIndex
34165
34177
  } = props.state;
34166
34178
  const {
34167
- strings
34179
+ perseusStrings
34168
34180
  } = props;
34169
34181
  const shouldShowRemoveButton = showRemovePointButton && focusedPointIndex !== null;
34170
34182
  return /*#__PURE__*/React.createElement(View, {
@@ -34182,7 +34194,7 @@ const renderPointGraphControls = props => {
34182
34194
  onClick: () => {
34183
34195
  props.dispatch(actions.pointGraph.addPoint([0, 0]));
34184
34196
  }
34185
- }, strings.addPoint), interactionMode === "mouse" && /*#__PURE__*/React.createElement(Button, {
34197
+ }, perseusStrings.addPoint), interactionMode === "mouse" && /*#__PURE__*/React.createElement(Button, {
34186
34198
  id: REMOVE_BUTTON_ID,
34187
34199
  kind: "secondary",
34188
34200
  color: "destructive"
@@ -34195,17 +34207,66 @@ const renderPointGraphControls = props => {
34195
34207
  marginLeft: "20px",
34196
34208
  visibility: shouldShowRemoveButton ? "visible" : "hidden"
34197
34209
  },
34198
- onClick: event => {
34210
+ onClick: _event => {
34199
34211
  props.dispatch(actions.pointGraph.removePoint(props.state.focusedPointIndex));
34200
34212
  }
34201
- }, strings.removePoint));
34213
+ }, perseusStrings.removePoint));
34214
+ };
34215
+
34216
+ /**
34217
+ * TODO(catjohnson): The polygon controls will be vastly different from the point controls.
34218
+ * Will be keeping this function as is for the time being, even if it's a copy of the point graph
34219
+ * controls.
34220
+ */
34221
+ const renderPolygonGraphControls = props => {
34222
+ const {
34223
+ interactionMode,
34224
+ showRemovePointButton,
34225
+ focusedPointIndex
34226
+ } = props.state;
34227
+ const {
34228
+ perseusStrings
34229
+ } = props;
34230
+ const shouldShowRemoveButton = showRemovePointButton && focusedPointIndex !== null;
34231
+ return /*#__PURE__*/React.createElement(View, {
34232
+ style: {
34233
+ flexDirection: "row",
34234
+ width: props.width
34235
+ }
34236
+ }, interactionMode === "keyboard" && /*#__PURE__*/React.createElement(Button, {
34237
+ kind: "secondary",
34238
+ style: {
34239
+ width: "100%",
34240
+ marginLeft: "20px"
34241
+ },
34242
+ tabIndex: 0,
34243
+ onClick: () => {
34244
+ props.dispatch(actions.polygon.addPoint([0, 0]));
34245
+ }
34246
+ }, perseusStrings.addPoint), interactionMode === "mouse" && /*#__PURE__*/React.createElement(Button, {
34247
+ id: REMOVE_BUTTON_ID,
34248
+ kind: "secondary",
34249
+ color: "destructive"
34250
+ // This button is meant to be interacted with by the mouse only
34251
+ // Never allow learners to tab to this button
34252
+ ,
34253
+ tabIndex: -1,
34254
+ style: {
34255
+ width: "100%",
34256
+ marginLeft: "20px",
34257
+ visibility: shouldShowRemoveButton ? "visible" : "hidden"
34258
+ },
34259
+ onClick: _event => {
34260
+ props.dispatch(actions.polygon.removePoint(props.state.focusedPointIndex));
34261
+ }
34262
+ }, perseusStrings.removePoint));
34202
34263
  };
34203
34264
  const renderGraphControls = props => {
34204
34265
  const {
34205
34266
  state,
34206
34267
  dispatch,
34207
34268
  width,
34208
- strings
34269
+ perseusStrings
34209
34270
  } = props;
34210
34271
  const {
34211
34272
  type
@@ -34217,7 +34278,17 @@ const renderGraphControls = props => {
34217
34278
  state,
34218
34279
  dispatch,
34219
34280
  width,
34220
- strings
34281
+ perseusStrings
34282
+ });
34283
+ }
34284
+ return null;
34285
+ case "polygon":
34286
+ if (state.numSides === "unlimited") {
34287
+ return renderPolygonGraphControls({
34288
+ state,
34289
+ dispatch,
34290
+ width,
34291
+ perseusStrings
34221
34292
  });
34222
34293
  }
34223
34294
  return null;
@@ -34226,21 +34297,29 @@ const renderGraphControls = props => {
34226
34297
  }
34227
34298
  };
34228
34299
  function handleFocusEvent(event, state, dispatch) {
34229
- if (state.type === "point" && state.numPoints === "unlimited") {
34300
+ if (isUnlimitedGraphState(state)) {
34230
34301
  if (event.target.classList.contains("mafs-graph") && state.interactionMode === "mouse") {
34231
34302
  dispatch(actions.global.changeKeyboardInvitationVisibility(true));
34232
34303
  }
34233
34304
  }
34234
34305
  }
34235
- function handleBlurEvent(event, state, dispatch) {
34236
- if (state.type === "point" && state.numPoints === "unlimited") {
34306
+ function handleBlurEvent(_event, state, dispatch) {
34307
+ if (isUnlimitedGraphState(state)) {
34237
34308
  dispatch(actions.global.changeKeyboardInvitationVisibility(false));
34238
34309
  }
34239
34310
  }
34240
34311
  function handleKeyboardEvent(event, state, dispatch) {
34241
- if (state.type === "point" && state.numPoints === "unlimited") {
34312
+ if (isUnlimitedGraphState(state)) {
34242
34313
  if (event.key === "Backspace") {
34243
- dispatch(actions.global.deleteIntent());
34314
+ var _document$activeEleme;
34315
+ // TODO(benchristel): Checking classList here is a hack to prevent
34316
+ // points from being deleted if the user presses the backspace key
34317
+ // while the whole graph is focused. Instead of doing this, we
34318
+ // should move the keyboard event handler to the movable point
34319
+ // handle element.
34320
+ if ((_document$activeEleme = document.activeElement) != null && _document$activeEleme.classList.contains("movable-point__focusable-handle")) {
34321
+ dispatch(actions.global.deleteIntent());
34322
+ }
34244
34323
 
34245
34324
  // After removing a point blur
34246
34325
  // It would be nice if this could focus on the graph but doing so
@@ -34483,10 +34562,15 @@ function initializeGraphState(params) {
34483
34562
  case "polygon":
34484
34563
  return _extends({}, shared, {
34485
34564
  type: "polygon",
34565
+ numSides: graph.numSides || 0,
34486
34566
  showAngles: Boolean(graph.showAngles),
34487
34567
  showSides: Boolean(graph.showSides),
34488
34568
  coords: getPolygonCoords(graph, range, step),
34489
- snapTo: (_graph$snapTo = graph.snapTo) != null ? _graph$snapTo : "grid"
34569
+ snapTo: (_graph$snapTo = graph.snapTo) != null ? _graph$snapTo : "grid",
34570
+ focusedPointIndex: null,
34571
+ showRemovePointButton: false,
34572
+ interactionMode: "mouse",
34573
+ showKeyboardInteractionInvitation: false
34490
34574
  });
34491
34575
  case "point":
34492
34576
  return _extends({}, shared, {
@@ -34776,10 +34860,9 @@ function interactiveGraphReducer(state, action) {
34776
34860
  }
34777
34861
  function doDeleteIntent(state, action) {
34778
34862
  // For unlimited point graphs
34779
- if (state.type === "point" && state.numPoints === "unlimited") {
34780
- // if there's a focused point
34863
+ if (isUnlimitedGraphState(state)) {
34864
+ // Remove the last point that was focused, if any
34781
34865
  if (state.focusedPointIndex !== null) {
34782
- // Remove the focused focus
34783
34866
  return doRemovePoint(state, actions.pointGraph.removePoint(state.focusedPointIndex));
34784
34867
  }
34785
34868
  }
@@ -34787,6 +34870,7 @@ function doDeleteIntent(state, action) {
34787
34870
  }
34788
34871
  function doFocusPoint(state, action) {
34789
34872
  switch (state.type) {
34873
+ case "polygon":
34790
34874
  case "point":
34791
34875
  return _extends({}, state, {
34792
34876
  focusedPointIndex: action.index
@@ -34797,6 +34881,7 @@ function doFocusPoint(state, action) {
34797
34881
  }
34798
34882
  function doBlurPoint(state, action) {
34799
34883
  switch (state.type) {
34884
+ case "polygon":
34800
34885
  case "point":
34801
34886
  const nextState = _extends({}, state, {
34802
34887
  showRemovePointButton: false
@@ -34810,10 +34895,7 @@ function doBlurPoint(state, action) {
34810
34895
  }
34811
34896
  }
34812
34897
  function doClickPoint(state, action) {
34813
- if (state.type !== "point") {
34814
- return state;
34815
- }
34816
- if (state.numPoints === "unlimited") {
34898
+ if (isUnlimitedGraphState(state)) {
34817
34899
  return _extends({}, state, {
34818
34900
  focusedPointIndex: action.index,
34819
34901
  showRemovePointButton: true
@@ -34822,10 +34904,7 @@ function doClickPoint(state, action) {
34822
34904
  return state;
34823
34905
  }
34824
34906
  function doChangeInteractionMode(state, action) {
34825
- if (state.type !== "point") {
34826
- return state;
34827
- }
34828
- if (state.numPoints === "unlimited") {
34907
+ if (isUnlimitedGraphState(state)) {
34829
34908
  const nextKeyboardInvitation = action.mode === "keyboard" ? false : state.showKeyboardInteractionInvitation;
34830
34909
  return _extends({}, state, {
34831
34910
  interactionMode: action.mode,
@@ -34835,10 +34914,7 @@ function doChangeInteractionMode(state, action) {
34835
34914
  return state;
34836
34915
  }
34837
34916
  function doChangeKeyboardInvitationVisibility(state, action) {
34838
- if (state.type !== "point") {
34839
- return state;
34840
- }
34841
- if (state.numPoints === "unlimited") {
34917
+ if (isUnlimitedGraphState(state)) {
34842
34918
  return _extends({}, state, {
34843
34919
  showKeyboardInteractionInvitation: action.shouldShow,
34844
34920
  hasBeenInteractedWith: true
@@ -35169,7 +35245,7 @@ function doChangeRange(state, action) {
35169
35245
  });
35170
35246
  }
35171
35247
  function doAddPoint(state, action) {
35172
- if (state.type !== "point") {
35248
+ if (!isUnlimitedGraphState(state)) {
35173
35249
  return state;
35174
35250
  }
35175
35251
  const {
@@ -35193,7 +35269,7 @@ function doAddPoint(state, action) {
35193
35269
  });
35194
35270
  }
35195
35271
  function doRemovePoint(state, action) {
35196
- if (state.type !== "point") {
35272
+ if (!isUnlimitedGraphState(state)) {
35197
35273
  return state;
35198
35274
  }
35199
35275
  let nextFocusedPointIndex;
@@ -37499,9 +37575,6 @@ function shouldUseMafs(mafsFlags, graph) {
37499
37575
  return Boolean(mafsFlags["point"]);
37500
37576
  case "polygon":
37501
37577
  if (graph.numSides === UNLIMITED) {
37502
- // TODO(benchristel): add a feature flag for the "unlimited"
37503
- // case once we've implemented polygon graphs with unlimited
37504
- // sides
37505
37578
  return Boolean(mafsFlags["unlimited-polygon"]);
37506
37579
  }
37507
37580
  return Boolean(mafsFlags["polygon"]);
@@ -37519,974 +37592,15 @@ var InteractiveGraph$1 = {
37519
37592
  validator: interactiveGraphValidator
37520
37593
  };
37521
37594
 
37522
- const black = "#000000";
37523
- const grayDarker = "#333333";
37524
- const grayDark = "#555555";
37525
- const gray = "#999999";
37526
- const grayLight = "#AAAAAA";
37527
- const grayLighter = "#DDDDDD";
37528
- const white = "#FFFFFF";
37529
- const blue = "#005A88";
37530
- const blueDark = "#2C3747";
37531
- const green = "#76A005";
37532
- const red = "#CF5044";
37533
- const yellow = "#FFC40D";
37534
- const orange = "#BF4F04";
37535
- const pink = "#C3325F";
37536
- const purple = "#7A43B6";
37537
- const bodyBackground = "#FFFFFF";
37538
- const textColor = "#444444";
37539
- const linkColor = "#005987";
37540
- const linkColorHover = "#678D00";
37541
- const sansFontFamily = "'Helvetica Neue',Helvetica,Arial,sans-serif";
37542
- const serifFontFamily = "Georgia,'Times New Roman',Times,serif";
37543
- const monoFontFamily = "Monaco,Menlo,Consolas,'Courier New',monospace";
37544
- const baseFontSize = "14px";
37545
- const baseFontFamily = "inherit";
37546
- const baseLineHeight = "20px";
37547
- const altFontFamily = "Georgia,'Times New Roman',Times,serif";
37548
- const headingsFontFamily = "inherit";
37549
- const headingsFontWeight = "bold";
37550
- const headingsColor = "inherit";
37551
- const fontSizeLarge = "18px";
37552
- const fontSizeSmall = "12px";
37553
- const fontSizeMini = "10.5px";
37554
- const paddingLarge = "11px 19px";
37555
- const paddingSmall = "2px 10px";
37556
- const paddingMini = "0 6px";
37557
- const baseBorderRadius = "4px";
37558
- const borderRadiusLarge = "6px";
37559
- const borderRadiusSmall = "3px";
37560
- const tableBackground = "#000000";
37561
- const tableBackgroundAccent = "#F9F9F9";
37562
- const tableBackgroundHover = "#F5F5F5";
37563
- const tableBorder = "#DDDDDD";
37564
- const btnBackground = "#FFFFFF";
37565
- const btnBackgroundHighlight = "rgb(230, 230, 230)";
37566
- const btnBorder = "#CCCCCC";
37567
- const btnPrimaryBackground = "#0088CC";
37568
- const btnPrimaryBackgroundHighlight = "rgb(0, 68, 204)";
37569
- const btnInfoBackground = "#5BC0DE";
37570
- const btnInfoBackgroundHighlight = "#2F96B4";
37571
- const btnSuccessBackground = "#62C462";
37572
- const btnSuccessBackgroundHighlight = "#51A351";
37573
- const btnWarningBackground = "rgb(251, 180, 81)";
37574
- const btnWarningBackgroundHighlight = "#F89406";
37575
- const btnDangerBackground = "#EE5F5B";
37576
- const btnDangerBackgroundHighlight = "#BD362F";
37577
- const btnInverseBackground = "#444444";
37578
- const btnInverseBackgroundHighlight = "#222222";
37579
- const inputBackground = "#FFFFFF";
37580
- const inputBorder = "#CCCCCC";
37581
- const inputBorderRadius = "4px";
37582
- const inputDisabledBackground = "#EEEEEE";
37583
- const formActionsBackground = "#F5F5F5";
37584
- const inputHeight = "30px";
37585
- const dropdownBackground = "#FFFFFF";
37586
- const dropdownBorder = "rgba(0, 0, 0, 0.2)";
37587
- const dropdownDividerTop = "#E5E5E5";
37588
- const dropdownDividerBottom = "#FFFFFF";
37589
- const dropdownLinkColor = "#333333";
37590
- const dropdownLinkColorHover = "#FFFFFF";
37591
- const dropdownLinkColorActive = "#FFFFFF";
37592
- const dropdownLinkBackgroundActive = "#0088CC";
37593
- const dropdownLinkBackgroundHover = "#0088CC";
37594
- const zindexDropdown = 1000;
37595
- const zindexPopover = 1010;
37596
- const zindexTooltip = 1030;
37597
- const zindexFixedNavbar = 1030;
37598
- const zindexHeader = 1060;
37599
- const zindexModalBackdrop = 1070;
37600
- const zindexModal = 1080;
37601
- const zindexAboveModal = 1090;
37602
- const iconSpritePath = "../img/glyphicons-halflings.png";
37603
- const iconWhiteSpritePath = "../img/glyphicons-halflings-white.png";
37604
- const placeholderText = "#999999";
37605
- const hrBorder = "#EEEEEE";
37606
- const horizontalComponentOffset = "180px";
37607
- const wellBackground = "#F5F5F5";
37608
- const navbarCollapseWidth = "979px";
37609
- const navbarCollapseDesktopWidth = "980px";
37610
- const navbarHeight = "40px";
37611
- const navbarBackgroundHighlight = "#FFFFFF";
37612
- const navbarBackground = "rgb(242, 242, 242)";
37613
- const navbarBorder = "rgb(212, 212, 212)";
37614
- const navbarText = "#777777";
37615
- const navbarLinkColor = "#777777";
37616
- const navbarLinkColorHover = "#333333";
37617
- const navbarLinkColorActive = "#555555";
37618
- const navbarLinkBackgroundHover = "#000000";
37619
- const navbarLinkBackgroundActive = "rgb(230, 230, 230)";
37620
- const navbarBrandColor = "#777777";
37621
- const navbarInverseBackground = "#111111";
37622
- const navbarInverseBackgroundHighlight = "#222222";
37623
- const navbarInverseBorder = "#252525";
37624
- const navbarInverseText = "#999999";
37625
- const navbarInverseLinkColor = "#999999";
37626
- const navbarInverseLinkColorHover = "#FFFFFF";
37627
- const navbarInverseLinkColorActive = "#FFFFFF";
37628
- const navbarInverseLinkBackgroundHover = "#000000";
37629
- const navbarInverseLinkBackgroundActive = "#111111";
37630
- const navbarInverseSearchBackground = "rgb(82, 82, 82)";
37631
- const navbarInverseSearchBackgroundFocus = "#FFFFFF";
37632
- const navbarInverseSearchBorder = "#111111";
37633
- const navbarInverseSearchPlaceholderColor = "#CCCCCC";
37634
- const navbarInverseBrandColor = "#999999";
37635
- const paginationBackground = "#FFFFFF";
37636
- const paginationBorder = "#DDDDDD";
37637
- const paginationActiveBackground = "#F5F5F5";
37638
- const heroUnitBackground = "#EEEEEE";
37639
- const heroUnitHeadingColor = "inherit";
37640
- const heroUnitLeadColor = "inherit";
37641
- const warningText = "#C09853";
37642
- const warningBackground = "#FCF8E3";
37643
- const warningBorder = "rgb(251, 239, 213)";
37644
- const errorText = "#B94A48";
37645
- const errorBackground = "#F2DEDE";
37646
- const errorBorder = "rgb(238, 211, 215)";
37647
- const successText = "#468847";
37648
- const successBackground = "#DFF0D8";
37649
- const successBorder = "rgb(212, 232, 197)";
37650
- const infoText = "#4A7C17";
37651
- const infoBackground = "#EDF2DF";
37652
- const infoBorder = "rgb(228, 232, 197)";
37653
- const tooltipColor = "#FFFFFF";
37654
- const tooltipBackground = "#000000";
37655
- const tooltipArrowWidth = "5px";
37656
- const tooltipArrowColor = "#000000";
37657
- const popoverBackground = "#FFFFFF";
37658
- const popoverArrowWidth = "10px";
37659
- const popoverArrowColor = "#FFFFFF";
37660
- const popoverTitleBackground = "rgb(247, 247, 247)";
37661
- const popoverArrowOuterWidth = "11px";
37662
- const popoverArrowOuterColor = "rgba(0, 0, 0, 0.25)";
37663
- const gridColumns = "12";
37664
- const gridColumnWidth = "60px";
37665
- const gridGutterWidth = "20px";
37666
- const gridRowWidth = "940px";
37667
- const gridColumnWidth1200 = "70px";
37668
- const gridGutterWidth1200 = "30px";
37669
- const gridRowWidth1200 = "1170px";
37670
- const gridColumnWidth768 = "42px";
37671
- const gridGutterWidth768 = "20px";
37672
- const gridRowWidth768 = "724px";
37673
- const fluidGridColumnWidth = "6.382978723404255%";
37674
- const fluidGridGutterWidth = "2.127659574468085%";
37675
- const fluidGridColumnWidth1200 = "5.982905982905983%";
37676
- const fluidGridGutterWidth1200 = "2.564102564102564%";
37677
- const fluidGridColumnWidth768 = "5.801104972375691%";
37678
- const fluidGridGutterWidth768 = "2.7624309392265194%";
37679
- const kaGreen = "#71B307";
37680
- const kaGreenLight = "#BED47A";
37681
- const kaBlue = "#314453";
37682
- const kaBlueLight = "#4D6779";
37683
- const grayExtraDark = "#111111";
37684
- const grayExtraLight = "#EEEEEE";
37685
- const graySuperLight = "#F7F7F7";
37686
- const whiteDark = "#FDFDFD";
37687
- const dark = "#21242C";
37688
- const blueDarkUnsaturated = "#3B414E";
37689
- const blueDarkSaturated = "#1F3043";
37690
- const blueLight = "#A9C0D1";
37691
- const greenLight = "#C6D1AD";
37692
- const greenDark = "#356700";
37693
- const yellowGreen = "#9DB63B";
37694
- const okGreen = "#A7CF5B";
37695
- const alertRed = "#C42420";
37696
- const coral = "#EE6666";
37697
- const grayBlue = "#9AB3B9";
37698
- const lightPageBackground = "#FDFDFD";
37699
- const yclaBlue = "#49BAD5";
37700
- const yclaTeal = "#56D0B3";
37701
- const yclaTealDark = "#50C1A7";
37702
- const yclaGreenDark = "#3D9A82";
37703
- const yclaGreen = "#81C262";
37704
- const learnstormBlue = "#4898FC";
37705
- const homepageBlue = "#46A8BF";
37706
- const backgroundBlue = "#00294A";
37707
- const teacherSignupBlue = "#335d7d";
37708
- const homepageGreen = "#2B8E7B";
37709
- const streakColor = "#F79734";
37710
- const facebookColor = "#1A60A2";
37711
- const blueGoogleColor = "#2CAFE2";
37712
- const redGoogleColor = "#BF4434";
37713
- const homepageColor = "#2D585E";
37714
- const lightTextColor = "#898989";
37715
- const fontSizeTiny = "11px";
37716
- const fontSizeNormal = "14px";
37717
- const fontSizeMedium = "16px";
37718
- const fontSizeExtraLarge = "24px";
37719
- const fontSizeHuge = "36px";
37720
- const fontSizeBakana = "48px";
37721
- const fontSizeBananas = "60px";
37722
- const fixedWidthFontFamily = "'Helvetica Neue',Helvetica,Arial,sans-serif";
37723
- const contentPadding = "20px";
37724
- const primaryButtonBackground = "#89B908";
37725
- const primaryButtonBorder = "#76A005";
37726
- const buttonTextColor = "rgb(122, 122, 122)";
37727
- const buttonBorderRadius = "3px";
37728
- const basicBorderColor = "#CCCCCC";
37729
- const minContainerWidth = "1000px";
37730
- const maxContainerWidth = "1200px";
37731
- const formHintColor = "#999999";
37732
- const guidelineExampleText = "#606060";
37733
- const hoverCardWidth = "450px";
37734
- const menuHighlightColor = "#96AB4F";
37735
- const menuHighlightBorderColor = "#76A005";
37736
- const menuActiveTextColor = "#FFFFFF";
37737
- const menuInactiveTextColor = "#444444";
37738
- const menuSubheaderTextColor = "rgb(120, 120, 120)";
37739
- const menuBorderColor = "#94A170";
37740
- const unreadBackgroundColor = "#ECEEF4";
37741
- const menuLineHeight = "18px";
37742
- const menuSubheaderLineHeight = "17px";
37743
- const menuSubheaderFontSize = "9px";
37744
- const notificationBarColor = "#4858A4";
37745
- const modalBodyTopPadding = "20px";
37746
- const modalDialogPadding = "15px";
37747
- const modalSectionPadding = "9px";
37748
- const mathDomain1 = "#11ACCD";
37749
- const mathDomain2 = "#63D9EA";
37750
- const mathDomain3 = "#027d97";
37751
- const mathDomain4 = "#085566";
37752
- const partnerContentDomain1 = "#01A995";
37753
- const partnerContentDomain2 = "#01D1C1";
37754
- const partnerContentDomain3 = "#208170";
37755
- const partnerContentDomain4 = "#144F44";
37756
- const csDomain1 = "#1FAB54";
37757
- const csDomain2 = "#74CF70";
37758
- const csDomain3 = "#0D923F";
37759
- const csDomain4 = "#085E29";
37760
- const economicsDomain1 = "#E07D10";
37761
- const economicsDomain2 = "#FFBE26";
37762
- const economicsDomain3 = "#A75A05";
37763
- const economicsDomain4 = "#953C02";
37764
- const collegeCareersMoreDomain1 = "#01A995";
37765
- const collegeCareersMoreDomain2 = "#01D1C1";
37766
- const collegeCareersMoreDomain3 = "#208170";
37767
- const collegeCareersMoreDomain4 = "#144F44";
37768
- const humanitiesDomain1 = "#E84D39";
37769
- const humanitiesDomain2 = "#FF8482";
37770
- const humanitiesDomain3 = "#BE2612";
37771
- const humanitiesDomain4 = "#8C1C0D";
37772
- const gtpDomain1 = "#1865F2";
37773
- const gtpDomain2 = "#1865F2";
37774
- const gtpDomain3 = "#1865F2";
37775
- const gtpDomain4 = "#1865F2";
37776
- const scienceDomain1 = "#CA337C";
37777
- const scienceDomain2 = "#FF92C6";
37778
- const scienceDomain3 = "#9E034E";
37779
- const scienceDomain4 = "#6B0235";
37780
- const testPrepDomain1 = "#1865F2";
37781
- const testPrepDomain2 = "#1865F2";
37782
- const testPrepDomain3 = "#1865F2";
37783
- const testPrepDomain4 = "#1865F2";
37784
- const defaultDomain1 = "#1865F2";
37785
- const defaultDomain2 = "#66afe9";
37786
- const defaultDomain3 = "#1152b0";
37787
- const defaultDomain4 = "#0d3d82";
37788
- const defaultDomainColor = "#314453";
37789
- const defaultSubjectColor = "#4D6779";
37790
- const defaultTopicColor = "#6A8DA6";
37791
- const defaultHoverColor = "#314453";
37792
- const defaultLinkColor = "#314453";
37793
- const defaultLinkHoverColor = "#6A8DA6";
37794
- const scienceDomainColor = "#94424F";
37795
- const scienceSubjectColor = "#9D4A5A";
37796
- const scienceTopicColor = "#C55F73";
37797
- const scienceHoverColor = "#94424F";
37798
- const scienceLinkColor = "#94424F";
37799
- const scienceLinkHoverColor = "#C55F73";
37800
- const humanitiesDomainColor = "#AD3434";
37801
- const humanitiesSubjectColor = "#C13B31";
37802
- const humanitiesTopicColor = "#D24A45";
37803
- const humanitiesHoverColor = "#AD3434";
37804
- const humanitiesLinkColor = "#AD3434";
37805
- const humanitiesLinkHoverColor = "#D24A45";
37806
- const economicsDomainColor = "#B77033";
37807
- const economicsSubjectColor = "#BF7B34";
37808
- const economicsTopicColor = "#D1933B";
37809
- const economicsHoverColor = "#B77033";
37810
- const economicsLinkColor = "#B77033";
37811
- const economicsLinkHoverColor = "#D1933B";
37812
- const csDomainColor = "#437A39";
37813
- const csSubjectColor = "#53893E";
37814
- const csTopicColor = "#689B51";
37815
- const csHoverColor = "#437A39";
37816
- const csLinkColor = "#437A39";
37817
- const csLinkHoverColor = "#689B51";
37818
- const partnerContentDomainColor = "#218270";
37819
- const partnerContentSubjectColor = "#2C8D7B";
37820
- const partnerContentTopicColor = "#329A86";
37821
- const partnerContentHoverColor = "#218270";
37822
- const partnerContentLinkColor = "#218270";
37823
- const partnerContentLinkHoverColor = "#329A86";
37824
- const essayDomainColor = "#0071B3";
37825
- const mathDomainColor = "#1C758A";
37826
- const mathSubjectColor = "#46A8BF";
37827
- const mathTopicColor = "#4FBAD4";
37828
- const mathHoverColor = "#1C758A";
37829
- const mathLinkColor = "#1C758A";
37830
- const mathLinkHoverColor = "#4FBAD4";
37831
- const testPrepDomainColor = "#644172";
37832
- const testPrepSubjectColor = "#7E5F8E";
37833
- const testPrepTopicColor = "#9A72AC";
37834
- const testPrepHoverColor = "#644172";
37835
- const testPrepLinkColor = "#644172";
37836
- const testPrepLinkHoverColor = "#9A72AC";
37837
- const collegeCareersMoreDomainColor = "#218270";
37838
- const collegeCareersMoreSubjectColor = "#2C8D7B";
37839
- const collegeCareersMoreTopicColor = "#329A86";
37840
- const collegeCareersMoreHoverColor = "#218270";
37841
- const collegeCareersMoreLinkColor = "#218270";
37842
- const collegeCareersMoreLinkHoverColor = "#329A86";
37843
- const colorProficient = "#1C758A";
37844
- const colorPracticed = "rgb(158, 221, 235)";
37845
- const colorMastery1 = "rgb(90, 197, 221)";
37846
- const colorMastery2 = "rgb(42, 174, 203)";
37847
- const colorMastery3 = "#1C758A";
37848
- const colorSuggested = "#73982C";
37849
- const colorReview = "#E35D04";
37850
- const colorNotStarted = "#CCCCCC";
37851
- const colorStarted = "#C7E5F7";
37852
- const colorStruggling = "#C30202";
37853
- const colorPersonal = "#00809C";
37854
- const colorPractice = "#96D9FF";
37855
- const colorEnergyPoints = "#005987";
37856
- const pureSmMin = "568px";
37857
- const pureMdMin = "768px";
37858
- const pureLgMin = "1024px";
37859
- const pureXlMin = "1200px";
37860
- const pureXsMax = "567px";
37861
- const pureSmMax = "767px";
37862
- const pureMdMax = "1023px";
37863
- const pureLgMax = "1199px";
37864
-
37865
- var globalConstants = /*#__PURE__*/Object.freeze({
37866
- __proto__: null,
37867
- black: black,
37868
- grayDarker: grayDarker,
37869
- grayDark: grayDark,
37870
- gray: gray,
37871
- grayLight: grayLight,
37872
- grayLighter: grayLighter,
37873
- white: white,
37874
- blue: blue,
37875
- blueDark: blueDark,
37876
- green: green,
37877
- red: red,
37878
- yellow: yellow,
37879
- orange: orange,
37880
- pink: pink,
37881
- purple: purple,
37882
- bodyBackground: bodyBackground,
37883
- textColor: textColor,
37884
- linkColor: linkColor,
37885
- linkColorHover: linkColorHover,
37886
- sansFontFamily: sansFontFamily,
37887
- serifFontFamily: serifFontFamily,
37888
- monoFontFamily: monoFontFamily,
37889
- baseFontSize: baseFontSize,
37890
- baseFontFamily: baseFontFamily,
37891
- baseLineHeight: baseLineHeight,
37892
- altFontFamily: altFontFamily,
37893
- headingsFontFamily: headingsFontFamily,
37894
- headingsFontWeight: headingsFontWeight,
37895
- headingsColor: headingsColor,
37896
- fontSizeLarge: fontSizeLarge,
37897
- fontSizeSmall: fontSizeSmall,
37898
- fontSizeMini: fontSizeMini,
37899
- paddingLarge: paddingLarge,
37900
- paddingSmall: paddingSmall,
37901
- paddingMini: paddingMini,
37902
- baseBorderRadius: baseBorderRadius,
37903
- borderRadiusLarge: borderRadiusLarge,
37904
- borderRadiusSmall: borderRadiusSmall,
37905
- tableBackground: tableBackground,
37906
- tableBackgroundAccent: tableBackgroundAccent,
37907
- tableBackgroundHover: tableBackgroundHover,
37908
- tableBorder: tableBorder,
37909
- btnBackground: btnBackground,
37910
- btnBackgroundHighlight: btnBackgroundHighlight,
37911
- btnBorder: btnBorder,
37912
- btnPrimaryBackground: btnPrimaryBackground,
37913
- btnPrimaryBackgroundHighlight: btnPrimaryBackgroundHighlight,
37914
- btnInfoBackground: btnInfoBackground,
37915
- btnInfoBackgroundHighlight: btnInfoBackgroundHighlight,
37916
- btnSuccessBackground: btnSuccessBackground,
37917
- btnSuccessBackgroundHighlight: btnSuccessBackgroundHighlight,
37918
- btnWarningBackground: btnWarningBackground,
37919
- btnWarningBackgroundHighlight: btnWarningBackgroundHighlight,
37920
- btnDangerBackground: btnDangerBackground,
37921
- btnDangerBackgroundHighlight: btnDangerBackgroundHighlight,
37922
- btnInverseBackground: btnInverseBackground,
37923
- btnInverseBackgroundHighlight: btnInverseBackgroundHighlight,
37924
- inputBackground: inputBackground,
37925
- inputBorder: inputBorder,
37926
- inputBorderRadius: inputBorderRadius,
37927
- inputDisabledBackground: inputDisabledBackground,
37928
- formActionsBackground: formActionsBackground,
37929
- inputHeight: inputHeight,
37930
- dropdownBackground: dropdownBackground,
37931
- dropdownBorder: dropdownBorder,
37932
- dropdownDividerTop: dropdownDividerTop,
37933
- dropdownDividerBottom: dropdownDividerBottom,
37934
- dropdownLinkColor: dropdownLinkColor,
37935
- dropdownLinkColorHover: dropdownLinkColorHover,
37936
- dropdownLinkColorActive: dropdownLinkColorActive,
37937
- dropdownLinkBackgroundActive: dropdownLinkBackgroundActive,
37938
- dropdownLinkBackgroundHover: dropdownLinkBackgroundHover,
37939
- zindexDropdown: zindexDropdown,
37940
- zindexPopover: zindexPopover,
37941
- zindexTooltip: zindexTooltip,
37942
- zindexFixedNavbar: zindexFixedNavbar,
37943
- zindexHeader: zindexHeader,
37944
- zindexModalBackdrop: zindexModalBackdrop,
37945
- zindexModal: zindexModal,
37946
- zindexAboveModal: zindexAboveModal,
37947
- iconSpritePath: iconSpritePath,
37948
- iconWhiteSpritePath: iconWhiteSpritePath,
37949
- placeholderText: placeholderText,
37950
- hrBorder: hrBorder,
37951
- horizontalComponentOffset: horizontalComponentOffset,
37952
- wellBackground: wellBackground,
37953
- navbarCollapseWidth: navbarCollapseWidth,
37954
- navbarCollapseDesktopWidth: navbarCollapseDesktopWidth,
37955
- navbarHeight: navbarHeight,
37956
- navbarBackgroundHighlight: navbarBackgroundHighlight,
37957
- navbarBackground: navbarBackground,
37958
- navbarBorder: navbarBorder,
37959
- navbarText: navbarText,
37960
- navbarLinkColor: navbarLinkColor,
37961
- navbarLinkColorHover: navbarLinkColorHover,
37962
- navbarLinkColorActive: navbarLinkColorActive,
37963
- navbarLinkBackgroundHover: navbarLinkBackgroundHover,
37964
- navbarLinkBackgroundActive: navbarLinkBackgroundActive,
37965
- navbarBrandColor: navbarBrandColor,
37966
- navbarInverseBackground: navbarInverseBackground,
37967
- navbarInverseBackgroundHighlight: navbarInverseBackgroundHighlight,
37968
- navbarInverseBorder: navbarInverseBorder,
37969
- navbarInverseText: navbarInverseText,
37970
- navbarInverseLinkColor: navbarInverseLinkColor,
37971
- navbarInverseLinkColorHover: navbarInverseLinkColorHover,
37972
- navbarInverseLinkColorActive: navbarInverseLinkColorActive,
37973
- navbarInverseLinkBackgroundHover: navbarInverseLinkBackgroundHover,
37974
- navbarInverseLinkBackgroundActive: navbarInverseLinkBackgroundActive,
37975
- navbarInverseSearchBackground: navbarInverseSearchBackground,
37976
- navbarInverseSearchBackgroundFocus: navbarInverseSearchBackgroundFocus,
37977
- navbarInverseSearchBorder: navbarInverseSearchBorder,
37978
- navbarInverseSearchPlaceholderColor: navbarInverseSearchPlaceholderColor,
37979
- navbarInverseBrandColor: navbarInverseBrandColor,
37980
- paginationBackground: paginationBackground,
37981
- paginationBorder: paginationBorder,
37982
- paginationActiveBackground: paginationActiveBackground,
37983
- heroUnitBackground: heroUnitBackground,
37984
- heroUnitHeadingColor: heroUnitHeadingColor,
37985
- heroUnitLeadColor: heroUnitLeadColor,
37986
- warningText: warningText,
37987
- warningBackground: warningBackground,
37988
- warningBorder: warningBorder,
37989
- errorText: errorText,
37990
- errorBackground: errorBackground,
37991
- errorBorder: errorBorder,
37992
- successText: successText,
37993
- successBackground: successBackground,
37994
- successBorder: successBorder,
37995
- infoText: infoText,
37996
- infoBackground: infoBackground,
37997
- infoBorder: infoBorder,
37998
- tooltipColor: tooltipColor,
37999
- tooltipBackground: tooltipBackground,
38000
- tooltipArrowWidth: tooltipArrowWidth,
38001
- tooltipArrowColor: tooltipArrowColor,
38002
- popoverBackground: popoverBackground,
38003
- popoverArrowWidth: popoverArrowWidth,
38004
- popoverArrowColor: popoverArrowColor,
38005
- popoverTitleBackground: popoverTitleBackground,
38006
- popoverArrowOuterWidth: popoverArrowOuterWidth,
38007
- popoverArrowOuterColor: popoverArrowOuterColor,
38008
- gridColumns: gridColumns,
38009
- gridColumnWidth: gridColumnWidth,
38010
- gridGutterWidth: gridGutterWidth,
38011
- gridRowWidth: gridRowWidth,
38012
- gridColumnWidth1200: gridColumnWidth1200,
38013
- gridGutterWidth1200: gridGutterWidth1200,
38014
- gridRowWidth1200: gridRowWidth1200,
38015
- gridColumnWidth768: gridColumnWidth768,
38016
- gridGutterWidth768: gridGutterWidth768,
38017
- gridRowWidth768: gridRowWidth768,
38018
- fluidGridColumnWidth: fluidGridColumnWidth,
38019
- fluidGridGutterWidth: fluidGridGutterWidth,
38020
- fluidGridColumnWidth1200: fluidGridColumnWidth1200,
38021
- fluidGridGutterWidth1200: fluidGridGutterWidth1200,
38022
- fluidGridColumnWidth768: fluidGridColumnWidth768,
38023
- fluidGridGutterWidth768: fluidGridGutterWidth768,
38024
- kaGreen: kaGreen,
38025
- kaGreenLight: kaGreenLight,
38026
- kaBlue: kaBlue,
38027
- kaBlueLight: kaBlueLight,
38028
- grayExtraDark: grayExtraDark,
38029
- grayExtraLight: grayExtraLight,
38030
- graySuperLight: graySuperLight,
38031
- whiteDark: whiteDark,
38032
- dark: dark,
38033
- blueDarkUnsaturated: blueDarkUnsaturated,
38034
- blueDarkSaturated: blueDarkSaturated,
38035
- blueLight: blueLight,
38036
- greenLight: greenLight,
38037
- greenDark: greenDark,
38038
- yellowGreen: yellowGreen,
38039
- okGreen: okGreen,
38040
- alertRed: alertRed,
38041
- coral: coral,
38042
- grayBlue: grayBlue,
38043
- lightPageBackground: lightPageBackground,
38044
- yclaBlue: yclaBlue,
38045
- yclaTeal: yclaTeal,
38046
- yclaTealDark: yclaTealDark,
38047
- yclaGreenDark: yclaGreenDark,
38048
- yclaGreen: yclaGreen,
38049
- learnstormBlue: learnstormBlue,
38050
- homepageBlue: homepageBlue,
38051
- backgroundBlue: backgroundBlue,
38052
- teacherSignupBlue: teacherSignupBlue,
38053
- homepageGreen: homepageGreen,
38054
- streakColor: streakColor,
38055
- facebookColor: facebookColor,
38056
- blueGoogleColor: blueGoogleColor,
38057
- redGoogleColor: redGoogleColor,
38058
- homepageColor: homepageColor,
38059
- lightTextColor: lightTextColor,
38060
- fontSizeTiny: fontSizeTiny,
38061
- fontSizeNormal: fontSizeNormal,
38062
- fontSizeMedium: fontSizeMedium,
38063
- fontSizeExtraLarge: fontSizeExtraLarge,
38064
- fontSizeHuge: fontSizeHuge,
38065
- fontSizeBakana: fontSizeBakana,
38066
- fontSizeBananas: fontSizeBananas,
38067
- fixedWidthFontFamily: fixedWidthFontFamily,
38068
- contentPadding: contentPadding,
38069
- primaryButtonBackground: primaryButtonBackground,
38070
- primaryButtonBorder: primaryButtonBorder,
38071
- buttonTextColor: buttonTextColor,
38072
- buttonBorderRadius: buttonBorderRadius,
38073
- basicBorderColor: basicBorderColor,
38074
- minContainerWidth: minContainerWidth,
38075
- maxContainerWidth: maxContainerWidth,
38076
- formHintColor: formHintColor,
38077
- guidelineExampleText: guidelineExampleText,
38078
- hoverCardWidth: hoverCardWidth,
38079
- menuHighlightColor: menuHighlightColor,
38080
- menuHighlightBorderColor: menuHighlightBorderColor,
38081
- menuActiveTextColor: menuActiveTextColor,
38082
- menuInactiveTextColor: menuInactiveTextColor,
38083
- menuSubheaderTextColor: menuSubheaderTextColor,
38084
- menuBorderColor: menuBorderColor,
38085
- unreadBackgroundColor: unreadBackgroundColor,
38086
- menuLineHeight: menuLineHeight,
38087
- menuSubheaderLineHeight: menuSubheaderLineHeight,
38088
- menuSubheaderFontSize: menuSubheaderFontSize,
38089
- notificationBarColor: notificationBarColor,
38090
- modalBodyTopPadding: modalBodyTopPadding,
38091
- modalDialogPadding: modalDialogPadding,
38092
- modalSectionPadding: modalSectionPadding,
38093
- mathDomain1: mathDomain1,
38094
- mathDomain2: mathDomain2,
38095
- mathDomain3: mathDomain3,
38096
- mathDomain4: mathDomain4,
38097
- partnerContentDomain1: partnerContentDomain1,
38098
- partnerContentDomain2: partnerContentDomain2,
38099
- partnerContentDomain3: partnerContentDomain3,
38100
- partnerContentDomain4: partnerContentDomain4,
38101
- csDomain1: csDomain1,
38102
- csDomain2: csDomain2,
38103
- csDomain3: csDomain3,
38104
- csDomain4: csDomain4,
38105
- economicsDomain1: economicsDomain1,
38106
- economicsDomain2: economicsDomain2,
38107
- economicsDomain3: economicsDomain3,
38108
- economicsDomain4: economicsDomain4,
38109
- collegeCareersMoreDomain1: collegeCareersMoreDomain1,
38110
- collegeCareersMoreDomain2: collegeCareersMoreDomain2,
38111
- collegeCareersMoreDomain3: collegeCareersMoreDomain3,
38112
- collegeCareersMoreDomain4: collegeCareersMoreDomain4,
38113
- humanitiesDomain1: humanitiesDomain1,
38114
- humanitiesDomain2: humanitiesDomain2,
38115
- humanitiesDomain3: humanitiesDomain3,
38116
- humanitiesDomain4: humanitiesDomain4,
38117
- gtpDomain1: gtpDomain1,
38118
- gtpDomain2: gtpDomain2,
38119
- gtpDomain3: gtpDomain3,
38120
- gtpDomain4: gtpDomain4,
38121
- scienceDomain1: scienceDomain1,
38122
- scienceDomain2: scienceDomain2,
38123
- scienceDomain3: scienceDomain3,
38124
- scienceDomain4: scienceDomain4,
38125
- testPrepDomain1: testPrepDomain1,
38126
- testPrepDomain2: testPrepDomain2,
38127
- testPrepDomain3: testPrepDomain3,
38128
- testPrepDomain4: testPrepDomain4,
38129
- defaultDomain1: defaultDomain1,
38130
- defaultDomain2: defaultDomain2,
38131
- defaultDomain3: defaultDomain3,
38132
- defaultDomain4: defaultDomain4,
38133
- defaultDomainColor: defaultDomainColor,
38134
- defaultSubjectColor: defaultSubjectColor,
38135
- defaultTopicColor: defaultTopicColor,
38136
- defaultHoverColor: defaultHoverColor,
38137
- defaultLinkColor: defaultLinkColor,
38138
- defaultLinkHoverColor: defaultLinkHoverColor,
38139
- scienceDomainColor: scienceDomainColor,
38140
- scienceSubjectColor: scienceSubjectColor,
38141
- scienceTopicColor: scienceTopicColor,
38142
- scienceHoverColor: scienceHoverColor,
38143
- scienceLinkColor: scienceLinkColor,
38144
- scienceLinkHoverColor: scienceLinkHoverColor,
38145
- humanitiesDomainColor: humanitiesDomainColor,
38146
- humanitiesSubjectColor: humanitiesSubjectColor,
38147
- humanitiesTopicColor: humanitiesTopicColor,
38148
- humanitiesHoverColor: humanitiesHoverColor,
38149
- humanitiesLinkColor: humanitiesLinkColor,
38150
- humanitiesLinkHoverColor: humanitiesLinkHoverColor,
38151
- economicsDomainColor: economicsDomainColor,
38152
- economicsSubjectColor: economicsSubjectColor,
38153
- economicsTopicColor: economicsTopicColor,
38154
- economicsHoverColor: economicsHoverColor,
38155
- economicsLinkColor: economicsLinkColor,
38156
- economicsLinkHoverColor: economicsLinkHoverColor,
38157
- csDomainColor: csDomainColor,
38158
- csSubjectColor: csSubjectColor,
38159
- csTopicColor: csTopicColor,
38160
- csHoverColor: csHoverColor,
38161
- csLinkColor: csLinkColor,
38162
- csLinkHoverColor: csLinkHoverColor,
38163
- partnerContentDomainColor: partnerContentDomainColor,
38164
- partnerContentSubjectColor: partnerContentSubjectColor,
38165
- partnerContentTopicColor: partnerContentTopicColor,
38166
- partnerContentHoverColor: partnerContentHoverColor,
38167
- partnerContentLinkColor: partnerContentLinkColor,
38168
- partnerContentLinkHoverColor: partnerContentLinkHoverColor,
38169
- essayDomainColor: essayDomainColor,
38170
- mathDomainColor: mathDomainColor,
38171
- mathSubjectColor: mathSubjectColor,
38172
- mathTopicColor: mathTopicColor,
38173
- mathHoverColor: mathHoverColor,
38174
- mathLinkColor: mathLinkColor,
38175
- mathLinkHoverColor: mathLinkHoverColor,
38176
- testPrepDomainColor: testPrepDomainColor,
38177
- testPrepSubjectColor: testPrepSubjectColor,
38178
- testPrepTopicColor: testPrepTopicColor,
38179
- testPrepHoverColor: testPrepHoverColor,
38180
- testPrepLinkColor: testPrepLinkColor,
38181
- testPrepLinkHoverColor: testPrepLinkHoverColor,
38182
- collegeCareersMoreDomainColor: collegeCareersMoreDomainColor,
38183
- collegeCareersMoreSubjectColor: collegeCareersMoreSubjectColor,
38184
- collegeCareersMoreTopicColor: collegeCareersMoreTopicColor,
38185
- collegeCareersMoreHoverColor: collegeCareersMoreHoverColor,
38186
- collegeCareersMoreLinkColor: collegeCareersMoreLinkColor,
38187
- collegeCareersMoreLinkHoverColor: collegeCareersMoreLinkHoverColor,
38188
- colorProficient: colorProficient,
38189
- colorPracticed: colorPracticed,
38190
- colorMastery1: colorMastery1,
38191
- colorMastery2: colorMastery2,
38192
- colorMastery3: colorMastery3,
38193
- colorSuggested: colorSuggested,
38194
- colorReview: colorReview,
38195
- colorNotStarted: colorNotStarted,
38196
- colorStarted: colorStarted,
38197
- colorStruggling: colorStruggling,
38198
- colorPersonal: colorPersonal,
38199
- colorPractice: colorPractice,
38200
- colorEnergyPoints: colorEnergyPoints,
38201
- pureSmMin: pureSmMin,
38202
- pureMdMin: pureMdMin,
38203
- pureLgMin: pureLgMin,
38204
- pureXlMin: pureXlMin,
38205
- pureXsMax: pureXsMax,
38206
- pureSmMax: pureSmMax,
38207
- pureMdMax: pureMdMax,
38208
- pureLgMax: pureLgMax
38209
- });
38210
-
38211
- const colors = {
38212
- white: "#FFFFFF",
38213
- gray98: "#FAFAFA",
38214
- gray97: "#F6F7F7",
38215
- gray95: "#F0F1F2",
38216
- gray90: "#E3E5E6",
38217
- gray85: "#D6D8DA",
38218
- gray76: "#BABEC2",
38219
- gray72: "#999A9D",
38220
- gray68: "#888D93",
38221
- gray55: "#707378",
38222
- gray41: "#626569",
38223
- gray25: "#3B3E40",
38224
- gray17: "#21242C",
38225
- gray10: "#1499af",
38226
- black: "#000000",
38227
- // These colors are pulled out from constants.js, which is itself generated
38228
- // from variables.less. We should probably avoid duplicating these here.
38229
- alertRed,
38230
- homepageBlue,
38231
- kaBlue,
38232
- kaBlueLight,
38233
- kaGreen,
38234
- kaGreenLight,
38235
- learnstormBlue,
38236
- backgroundBlue,
38237
- adminGreen: "#78C008",
38238
- kaBlueExtraLight: "#39c2db",
38239
- kaBlueHover: "#0c7f99",
38240
- kaGreenHover: "#518005",
38241
- // Domain-agnostic colors related to the study guide experience in the
38242
- // content library.
38243
- skyDark: "#001f4d",
38244
- recommendationGold: "#ffbe26",
38245
- starAced: "#ff9c39",
38246
- // We interploate the domain colors into this colors object for
38247
- // historical reasons, but everyone using domain-specific colors
38248
- // should switch to using the domainColors() function to look up
38249
- // colors instead.
38250
- //
38251
- // TODO(davidflanagan): remove this line once everything is
38252
- // working correctly with the domainColors() accessor.
38253
- // ...domainToColorsMap,
38254
- // mission: missionColors,
38255
-
38256
- // Colors for various OAuth providers
38257
- google: "#C1432f",
38258
- modernGoogle: "#be2612",
38259
- modernGoogleHover: "#8c1c0d",
38260
- facebook: "#4267B2",
38261
- modernFacebook: "#4267B2",
38262
- modernFacebookHover: "#00294a",
38263
- wonderBlocksGold: "#FFB100",
38264
- wonderBlocksLightBlue: "#37C5FD",
38265
- // We're using rgba instead of opacity to avoid affecting the focus outline
38266
- // when we just want to make the color transparent.
38267
- breadcrumbs: "rgba(255, 255, 255, 0.7)"
38268
- };
38269
- const borderRadius = 4;
38270
- const breadcrumbStyles = {
38271
- color: colors.breadcrumbs,
37595
+ // TODO: can we use WB typography?
37596
+ const bodyXsmallBold = {
37597
+ // For emphasized metadata, descriptions, etc
38272
37598
  fontFamily: "inherit",
38273
37599
  fontSize: 15,
38274
37600
  fontWeight: "bold",
38275
- letterSpacing: 0.8,
38276
- lineHeight: "19px",
38277
- textTransform: "uppercase",
38278
- // Disable subpixel antialiasing for OSX (improves light on dark text)
38279
- MozOsxFontSmoothing: "grayscale",
38280
- WebkitFontSmoothing: "antialiased"
38281
- };
38282
- const fonts = {
38283
- // The body of the page is setup to use 'Helvetica' by default and
38284
- // 'Lato' if/once it downloads. For your elements to follow this
38285
- // pattern, all you need is to make the text in your element
38286
- // inherit from the body using the "inherit" value.
38287
- regular: "inherit"
38288
- };
38289
- const typography = {
38290
- // For subject names
38291
- subjectHeadingDesktop: {
38292
- fontFamily: "inherit",
38293
- fontSize: 50,
38294
- fontWeight: "bold",
38295
- lineHeight: "61px"
38296
- },
38297
- subjectHeadingMobile: {
38298
- fontFamily: "inherit",
38299
- fontSize: 35,
38300
- fontWeight: "bold",
38301
- lineHeight: "37px"
38302
- },
38303
- // For the most important thing on the page
38304
- conceptHeadingDesktop: {
38305
- fontFamily: "inherit",
38306
- fontSize: 35,
38307
- fontWeight: "bold",
38308
- lineHeight: "37px"
38309
- },
38310
- conceptHeadingMobile: {
38311
- fontFamily: "inherit",
38312
- fontSize: 23,
38313
- fontWeight: "bold",
38314
- lineHeight: "27px"
38315
- },
38316
- // For sections or modules
38317
- subheadingDesktop: {
38318
- fontFamily: "inherit",
38319
- fontSize: 23,
38320
- fontWeight: "bold",
38321
- lineHeight: "27px"
38322
- },
38323
- subheadingMobile: {
38324
- fontFamily: "inherit",
38325
- fontSize: 20,
38326
- fontWeight: "bold",
38327
- lineHeight: "24px"
38328
- },
38329
- smallSubheadingDesktop: {
38330
- fontFamily: "inherit",
38331
- fontSize: 20,
38332
- lineHeight: 1.25
38333
- },
38334
- smallSubheadingMobile: {
38335
- fontFamily: "inherit",
38336
- fontSize: 15,
38337
- lineHeight: 1.25
38338
- },
38339
- // For callouts
38340
- smallHeading: {
38341
- color: colors.gray25,
38342
- fontFamily: "inherit",
38343
- fontSize: 17,
38344
- fontWeight: "bold",
38345
- lineHeight: "23px"
38346
- },
38347
- smallHeadingMobile: {
38348
- color: colors.gray25,
38349
- fontFamily: "inherit",
38350
- fontSize: 15,
38351
- fontWeight: "bold",
38352
- lineHeight: "18px"
38353
- },
38354
- // Accent headings
38355
- accentHeading: {
38356
- color: colors.gray68,
38357
- fontFamily: "inherit",
38358
- fontSize: 15,
38359
- fontWeight: "bold",
38360
- letterSpacing: 0.8,
38361
- lineHeight: "19px",
38362
- textTransform: "uppercase"
38363
- },
38364
- bodyLarge: {
38365
- // For articles with multiple paragraphs
38366
- fontFamily: fonts.regular,
38367
- fontSize: 20,
38368
- lineHeight: "30px"
38369
- },
38370
- bodySmall: {
38371
- // For small blocks of copy
38372
- fontFamily: fonts.regular,
38373
- fontSize: 17,
38374
- fontWeight: "normal",
38375
- lineHeight: "23px"
38376
- },
38377
- bodySmallBold: {
38378
- // For small blocks of copy
38379
- fontFamily: fonts.regular,
38380
- fontSize: 17,
38381
- fontWeight: "bold",
38382
- lineHeight: "23px"
38383
- },
38384
- bodyXsmall: {
38385
- // For metadata, descriptions, etc
38386
- fontFamily: fonts.regular,
38387
- fontSize: 15,
38388
- lineHeight: "22px"
38389
- },
38390
- bodyXsmallBold: {
38391
- // For emphasized metadata, descriptions, etc
38392
- fontFamily: "inherit",
38393
- fontSize: 15,
38394
- fontWeight: "bold",
38395
- lineHeight: "22px"
38396
- },
38397
- breadcrumb: breadcrumbStyles,
38398
- // For in-page tabs, breadcrumbs
38399
- breadcrumbSmall: _extends({}, breadcrumbStyles, {
38400
- fontSize: 12,
38401
- lineHeight: "13px"
38402
- }),
38403
- labelLarge: {
38404
- // For chiclets and thumbnail titles
38405
- fontFamily: "inherit",
38406
- fontSize: 23,
38407
- fontWeight: "bold",
38408
- lineHeight: "27px"
38409
- },
38410
- labelMedium: {
38411
- // For chiclets and thumbnail titles
38412
- fontFamily: "inherit",
38413
- fontSize: 15,
38414
- fontWeight: "bold",
38415
- lineHeight: "18px"
38416
- },
38417
- labelSmall: {
38418
- // Generally used with labelLarge, for breadcrumbs in thumbnails
38419
- fontFamily: fonts.regular,
38420
- fontSize: 12,
38421
- lineHeight: "14px"
38422
- },
38423
- caption: {
38424
- // For image captions
38425
- fontFamily: fonts.regular,
38426
- fontSize: 14,
38427
- fontStyle: "italic",
38428
- lineHeight: "17px"
38429
- },
38430
- desktopScalingOnMobile: {
38431
- // For when you need Mobile Safari and friends to stick to desktop
38432
- // sizes
38433
- MozTextSizeAdjust: "100%",
38434
- MsTextSizeAdjust: "100%",
38435
- WebkitTextSizeAdjust: "100%"
38436
- },
38437
- // TODO (josh): This should move to within <ModalHeader>
38438
- modalSubtitle: {
38439
- fontSize: 12,
38440
- lineHeight: 1.65,
38441
- // NOTE (josh): Font smoothing used here to create a 'medium' weight
38442
- // font, between normal and bold, on webkit browsers.
38443
- // This prop is an a11y risk when used on non-bold text, since it
38444
- // makes text very thin, but it's fine on bold text.
38445
- WebkitFontSmoothing: "antialiased",
38446
- fontWeight: "bold"
38447
- },
38448
- // HACK(kevinb): temporary wonder blocks styles for header only
38449
- // TODO(kevinb): use components from wonder-blocks-typography instead
38450
- wonderBlocksHeader: {
38451
- paddingLeft: 16,
38452
- paddingRight: 16,
38453
- paddingBottom: 24,
38454
- paddingTop: 34,
38455
- [mediaQueries.mdOrLarger]: {
38456
- paddingBottom: 32
38457
- }
38458
- },
38459
- // HACK(kevinb): temporary wonder blocks styles for header only
38460
- // TODO(kevinb): use components from wonder-blocks-typography instead
38461
- wonderBlocksTitle: {
38462
- color: colors.white,
38463
- fontWeight: 900,
38464
- // "Black" weight
38465
- fontSize: 28,
38466
- lineHeight: "32px",
38467
- margin: 0,
38468
- [mediaQueries.mdOrLarger]: {
38469
- fontSize: 36,
38470
- lineHeight: "40px"
38471
- }
38472
- },
38473
- // HACK(kevinb): temporary wonder blocks styles for header only
38474
- // TODO(kevinb): use components from wonder-blocks-typography instead
38475
- wonderBlocksLabelLarge: {
38476
- fontSize: 16,
38477
- lineHeight: "20px",
38478
- fontWeight: 700 // Bold
38479
- }
37601
+ lineHeight: "22px"
38480
37602
  };
38481
37603
 
38482
- var globalStyles = /*#__PURE__*/Object.freeze({
38483
- __proto__: null,
38484
- colors: colors,
38485
- borderRadius: borderRadius,
38486
- fonts: fonts,
38487
- typography: typography
38488
- });
38489
-
38490
37604
  const AnswerChoices = props => {
38491
37605
  const {
38492
37606
  strings
@@ -39322,7 +38436,7 @@ class LabelImage extends React.Component {
39322
38436
  const promptString = isMobile ? multipleAnswers ? strings.tapMultiple : strings.tapSingle : multipleAnswers ? strings.clickMultiple : strings.clickSingle;
39323
38437
  const choicesString = strings.choices;
39324
38438
  return /*#__PURE__*/React.createElement("div", {
39325
- className: classNames("perseus-label-image-widget-instructions", css(styles$a.instructions))
38439
+ className: classNames$1("perseus-label-image-widget-instructions", css(styles$a.instructions))
39326
38440
  }, /*#__PURE__*/React.createElement("div", {
39327
38441
  className: css(styles$a.instructionsCaption)
39328
38442
  }, promptString, " ", !hideChoices && choicesString), !hideChoices && /*#__PURE__*/React.createElement("div", {
@@ -39388,7 +38502,7 @@ const styles$a = StyleSheet.create({
39388
38502
  instructions: {
39389
38503
  paddingBottom: 16
39390
38504
  },
39391
- instructionsCaption: _extends({}, typography.bodyXsmallBold, {
38505
+ instructionsCaption: _extends({}, bodyXsmallBold, {
39392
38506
  paddingBottom: 16
39393
38507
  }),
39394
38508
  instructionsChoices: {
@@ -40659,7 +39773,7 @@ class Matrix extends React.Component {
40659
39773
  const highlightedCol = Math.max(cursorCol, matrixSize[1] - 1);
40660
39774
  const bracketHeight = (highlightedRow + 1) * (INPUT_HEIGHT + 2 * INPUT_MARGIN);
40661
39775
  const bracketOffset = (highlightedCol + 1) * (INPUT_WIDTH + 2 * INPUT_MARGIN);
40662
- const className = classNames({
39776
+ const className = classNames$1({
40663
39777
  "perseus-matrix": true,
40664
39778
  "static-mode": this.props.static,
40665
39779
  "the-matrix": this.state.enterTheMatrix >= 5
@@ -43224,9 +42338,9 @@ const makeSafeUrl = (urlString, locale) => {
43224
42338
  };
43225
42339
  const styles$6 = StyleSheet.create({
43226
42340
  widgetContainer: {
43227
- borderRadius: borderRadiusLarge,
42341
+ borderRadius: 6,
43228
42342
  borderWidth: 1,
43229
- borderColor: basicBorderColor,
42343
+ borderColor: "#CCC",
43230
42344
  padding: spacing.medium_16,
43231
42345
  paddingBottom: 0
43232
42346
  },
@@ -44717,7 +43831,7 @@ const init = function init(options) {
44717
43831
 
44718
43832
  // This file is processed by a Rollup plugin (replace) to inject the production
44719
43833
  const libName = "@khanacademy/perseus";
44720
- const libVersion = "39.0.1";
43834
+ const libVersion = "40.0.0";
44721
43835
  addLibraryVersionToPerseusDebug(libName, libVersion);
44722
43836
 
44723
43837
  const apiVersion = {
@@ -44849,7 +43963,7 @@ class ArticleRenderer extends React.Component {
44849
43963
  const apiOptions = _extends({}, ApiOptions.defaults, this.props.apiOptions, {
44850
43964
  isArticle: true
44851
43965
  });
44852
- const classes = classNames({
43966
+ const classes = classNames$1({
44853
43967
  "framework-perseus": true,
44854
43968
  "perseus-article": true,
44855
43969
  // NOTE(charlie): For exercises, this is applied outside of Perseus
@@ -44929,7 +44043,7 @@ class HintRenderer extends React.Component {
44929
44043
  const {
44930
44044
  isMobile
44931
44045
  } = apiOptions;
44932
- const classNames$1 = classNames("hint", !isMobile && "perseus-hint-renderer", isMobile && css(styles$3.newHint), isMobile && lastRendered && css(styles$3.lastRenderedNewHint), lastHint && "last-hint", lastRendered && "last-rendered", className);
44046
+ const classNames = classNames$1("hint", !isMobile && "perseus-hint-renderer", isMobile && css(styles$3.newHint), isMobile && lastRendered && css(styles$3.lastRenderedNewHint), lastHint && "last-hint", lastRendered && "last-rendered", className);
44933
44047
 
44934
44048
  // TODO(charlie): Allowing `customKeypad` would require that we
44935
44049
  // extend `ItemRenderer` to support nested inputs in the `HintsRenderer`.
@@ -44943,7 +44057,7 @@ class HintRenderer extends React.Component {
44943
44057
  /*#__PURE__*/
44944
44058
  // @ts-expect-error - TS2322 - Type 'string' is not assignable to type 'number | undefined'.
44945
44059
  React.createElement("div", {
44946
- className: classNames$1,
44060
+ className: classNames,
44947
44061
  tabIndex: "-1"
44948
44062
  }, !apiOptions.isMobile && /*#__PURE__*/React.createElement("span", {
44949
44063
  className: "perseus-sr-only"
@@ -44996,7 +44110,7 @@ const styles$3 = StyleSheet.create({
44996
44110
  },
44997
44111
  lastRenderedNewHint: {
44998
44112
  marginBottom: 0,
44999
- borderLeftColor: kaGreen$1
44113
+ borderLeftColor: kaGreen
45000
44114
  }
45001
44115
  });
45002
44116
 
@@ -45147,9 +44261,9 @@ class HintsRenderer extends React.Component {
45147
44261
  } = apiOptions;
45148
44262
  const showGetAnotherHint = getAnotherHint && hintsVisible > 0 && hintsVisible < this.props.hints.length;
45149
44263
  const hintRatioCopy = `(${hintsVisible}/${this.props.hints.length})`;
45150
- const classNames$1 = classNames(this.props.className, apiOptions.isMobile && hintsVisible > 0 && css(styles$2.mobileHintStylesHintsRenderer));
44264
+ const classNames = classNames$1(this.props.className, apiOptions.isMobile && hintsVisible > 0 && css(styles$2.mobileHintStylesHintsRenderer));
45151
44265
  return /*#__PURE__*/React.createElement("div", {
45152
- className: classNames$1
44266
+ className: classNames
45153
44267
  }, apiOptions.isMobile && hintsVisible > 0 && /*#__PURE__*/React.createElement("div", {
45154
44268
  className: css(styles$2.mobileHintStylesHintTitle, sharedStyles.responsiveLabel)
45155
44269
  }, this.context.strings.hints), hints, showGetAnotherHint && /*#__PURE__*/React.createElement("button", {
@@ -45186,7 +44300,7 @@ const styles$2 = StyleSheet.create({
45186
44300
  fontSize: "100%",
45187
44301
  fontFamily: "inherit",
45188
44302
  fontWeight: "bold",
45189
- color: kaGreen$1,
44303
+ color: kaGreen,
45190
44304
  padding: 0,
45191
44305
  position: "relative"
45192
44306
  },
@@ -45581,28 +44695,6 @@ const ref = /*#__PURE__*/React.forwardRef((props, ref) => /*#__PURE__*/React.cre
45581
44695
  ref: ref
45582
44696
  }))));
45583
44697
 
45584
- const devices = {
45585
- PHONE: "phone",
45586
- TABLET: "tablet",
45587
- DESKTOP: "desktop"
45588
- };
45589
-
45590
- // How many pixels do we reserve on the right-hand side of a preview
45591
- // for displaying lint indicators? This space needs to be reserved
45592
- // in DeviceFramer, but it is actually allocated in PerseusFrame
45593
- const lintGutterWidth = 36;
45594
-
45595
- // How wide a border does PerseusFrame draw? We need to allocate enough
45596
- // space for it in DeviceFramer.
45597
- const perseusFrameBorderWidth = 1;
45598
-
45599
- var constants = /*#__PURE__*/Object.freeze({
45600
- __proto__: null,
45601
- devices: devices,
45602
- lintGutterWidth: lintGutterWidth,
45603
- perseusFrameBorderWidth: perseusFrameBorderWidth
45604
- });
45605
-
45606
44698
  /**
45607
44699
  * Traverses a {content, widgets, images} renderer props object,
45608
44700
  * such as `itemData.question`
@@ -48289,5 +47381,17 @@ const EditorJsonify = {
48289
47381
  }
48290
47382
  };
48291
47383
 
48292
- export { ApiOptions, ArticleRenderer, BaseRadio, Categorizer$1 as Categorizer, changeable as Changeable, ClassNames, dependencies as Dependencies, EditorJsonify, Expression, util as GrapherUtil, Grapher$1 as GrapherWidget, HintRenderer, HintsRenderer, InputNumber$1 as InputNumber, InteractiveGraph$1 as InteractiveGraphWidget, ItemExtras, JiptParagraphs, KhanColors, KhanMath, context as LoadingContext, Log, Matrix$1 as MatrixWidget, MultiItems, NumericInput$1 as NumericInput, PerseusExpressionAnswerFormConsidered, PerseusI18nContext, PerseusI18nContextProvider, PerseusMarkdown, Plotter$1 as PlotterWidget, QUESTION_WIDGETS, Radio, Renderer, ref as ServerItemRenderer, sizingUtils as SizingUtils, Table$1 as TableWidget, Util, denylist as WIDGET_PROP_DENYLIST, widgets$1 as Widgets, addWidget, apiVersion, buildEmptyItemTreeForShape, buildMapper, components, constants, contentHasWidgetType, convertWidgetNameToEnum, displaySigFigs, generateTestCategorizerWidget, generateTestExpressionWidget, generateTestInteractiveGraphWidget, generateTestNumericInputWidget, generateTestPerseusItem, generateTestRadioWidget, genericPerseusItemData, getAngleCoords, getAnswerFromUserInput, getAnswersFromWidgets, getCircleCoords, getClockwiseAngle, getCorrectAnswerForWidgetId, getImagesWithoutAltData, getLineCoords, getLinearSystemCoords, getPointCoords, getPolygonCoords, getQuadraticCoords, getSegmentCoords, getSinusoidCoords, getValidWidgetIds, getWidgetFromWidgetMap, getWidgetIdsFromContent, getWidgetIdsFromContentByType, getWidgetTypeByWidgetId, getWidgetsFromWidgetMap, getWidgetsMapFromItemData, globalConstants, globalStyles, iconPaths as icons, init, injectWidgets, interactiveSizes$1 as interactiveSizes, isItemRenderableByVersion, isWidgetIdInContent, isWrongAnswerSupported, itemDataVersion, itemToTree, ItemVersion as itemVersion, libVersion, lockedFigureColors, lockedFigureFillStyles, makeSafeUrl, mediaQueries, parsePerseusItem, plotterPlotTypes, preprocessTex, registerAllWidgetsForTesting, shapes, shouldHaveIndividualAnswer, traverse, usePerseusI18n, violatingWidgets, allWidgets as widgets };
47384
+ /**
47385
+ * Main entry point
47386
+ */
47387
+ const GrapherUtil = {
47388
+ allTypes,
47389
+ DEFAULT_GRAPHER_PROPS,
47390
+ chooseType,
47391
+ defaultPlotProps,
47392
+ getEquationString,
47393
+ typeToButton
47394
+ };
47395
+
47396
+ export { ApiOptions, ArticleRenderer, BaseRadio, Categorizer$1 as Categorizer, changeable as Changeable, ClassNames, dependencies as Dependencies, EditorJsonify, Expression, GrapherUtil, Grapher$1 as GrapherWidget, HintRenderer, HintsRenderer, InputNumber$1 as InputNumber, InteractiveGraph$1 as InteractiveGraphWidget, ItemExtras, JiptParagraphs, KhanColors, KhanMath, context as LoadingContext, Log, Matrix$1 as MatrixWidget, MultiItems, NumericInput$1 as NumericInput, PerseusExpressionAnswerFormConsidered, PerseusI18nContext, PerseusI18nContextProvider, PerseusMarkdown, Plotter$1 as PlotterWidget, QUESTION_WIDGETS, Radio, Renderer, ref as ServerItemRenderer, Table$1 as TableWidget, Util, denylist as WIDGET_PROP_DENYLIST, widgets$1 as Widgets, addWidget, apiVersion, bodyXsmallBold, buildEmptyItemTreeForShape, buildMapper, components, containerSizeClass, contentHasWidgetType, convertWidgetNameToEnum, displaySigFigs, generateTestCategorizerWidget, generateTestExpressionWidget, generateTestInteractiveGraphWidget, generateTestNumericInputWidget, generateTestPerseusItem, generateTestRadioWidget, genericPerseusItemData, getAngleCoords, getAnswerFromUserInput, getAnswersFromWidgets, getCircleCoords, getClockwiseAngle, getCorrectAnswerForWidgetId, getImagesWithoutAltData, getInteractiveBoxFromSizeClass, getLineCoords, getLinearSystemCoords, getPointCoords, getPolygonCoords, getQuadraticCoords, getSegmentCoords, getSinusoidCoords, getValidWidgetIds, getWidgetFromWidgetMap, getWidgetIdsFromContent, getWidgetIdsFromContentByType, getWidgetTypeByWidgetId, getWidgetsFromWidgetMap, getWidgetsMapFromItemData, iconChevronDown, iconTrash, init, injectWidgets, interactiveSizes$1 as interactiveSizes, isItemRenderableByVersion, isWidgetIdInContent, isWrongAnswerSupported, itemDataVersion, itemToTree, ItemVersion as itemVersion, libVersion, lockedFigureColors, lockedFigureFillStyles, makeSafeUrl, mediaQueries, parsePerseusItem, plotterPlotTypes, preprocessTex, registerAllWidgetsForTesting, shapes, shouldHaveIndividualAnswer, traverse, usePerseusI18n, violatingWidgets, allWidgets as widgets };
48293
47397
  //# sourceMappingURL=index.js.map