@khanacademy/perseus 17.8.0 → 18.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/CHANGELOG.md +40 -0
  2. package/dist/es/index.css +0 -4
  3. package/dist/es/index.js +1422 -1021
  4. package/dist/es/index.js.map +1 -1
  5. package/dist/index.css +0 -4
  6. package/dist/index.d.ts +4 -2
  7. package/dist/index.js +1321 -954
  8. package/dist/index.js.map +1 -1
  9. package/dist/perseus-types.d.ts +4 -3
  10. package/dist/renderer.d.ts +6 -6
  11. package/dist/server-item-renderer.d.ts +2 -4
  12. package/dist/strings.js +1 -1
  13. package/dist/types.d.ts +19 -2
  14. package/dist/util/drawing-transform.d.ts +21 -0
  15. package/dist/util/extract-perseus-data.d.ts +26 -0
  16. package/dist/util/graph-bounds.d.ts +9 -0
  17. package/dist/util/graphie.d.ts +2 -0
  18. package/dist/util/interval.d.ts +1 -0
  19. package/dist/util/parse-perseus-json.d.ts +10 -0
  20. package/dist/util/tex.d.ts +1 -3
  21. package/dist/widgets/deprecated-standin/index.d.ts +4 -4
  22. package/dist/widgets/passage.d.ts +3 -3
  23. package/dist/widgets.d.ts +16 -6
  24. package/package.json +9 -9
  25. package/src/__tests__/extract-perseus-data.test.ts +1027 -0
  26. package/src/index.ts +6 -1
  27. package/src/init.ts +1 -1
  28. package/src/perseus-types.ts +4 -3
  29. package/src/renderer.tsx +12 -9
  30. package/src/server-item-renderer.tsx +2 -4
  31. package/src/styles/widgets/image.less +0 -3
  32. package/src/types.ts +19 -16
  33. package/src/util/drawing-transform.test.ts +67 -0
  34. package/src/util/drawing-transform.ts +102 -0
  35. package/src/util/extract-perseus-data.ts +539 -0
  36. package/src/util/graph-bounds.ts +23 -0
  37. package/src/util/graphie.ts +1167 -1258
  38. package/src/util/interactive.ts +2 -2
  39. package/src/util/interval.ts +4 -0
  40. package/src/util/parse-perseus-json.test.ts +10 -0
  41. package/src/util/parse-perseus-json.ts +13 -0
  42. package/src/util/tex.ts +11 -84
  43. package/src/widgets/__stories__/image.stories.tsx +12 -26
  44. package/src/widgets/__tests__/__snapshots__/grapher.test.ts.snap +72 -288
  45. package/src/widgets/__tests__/__snapshots__/interaction.test.ts.snap +5 -20
  46. package/src/widgets/__tests__/__snapshots__/interactive-graph.test.ts.snap +32 -128
  47. package/src/widgets/__tests__/__snapshots__/number-line.test.ts.snap +22 -88
  48. package/src/widgets/__tests__/__snapshots__/plotter.test.tsx.snap +12 -48
  49. package/src/widgets/deprecated-standin/__stories__/deprecated-standin.stories.tsx +8 -12
  50. package/src/widgets/deprecated-standin/__tests__/__snapshots__/deprecated-standin.test.ts.snap +6 -7
  51. package/src/widgets/deprecated-standin/index.tsx +8 -7
  52. package/src/widgets/interactive-graph.tsx +3 -2
  53. package/src/widgets/label-image/answer-pill.tsx +6 -1
  54. package/src/widgets/passage.tsx +5 -7
  55. package/src/widgets.ts +34 -10
  56. package/tsconfig-build.tsbuildinfo +1 -1
@@ -37,7 +37,7 @@ type Widget<Type extends string, Options> = {
37
37
  static?: boolean;
38
38
  graded?: boolean;
39
39
  alignment?: string;
40
- options: Options | null | undefined;
40
+ options: Options;
41
41
  key?: number;
42
42
  version?: Version;
43
43
  };
@@ -332,10 +332,11 @@ export type PerseusMatcherWidgetOptions = {
332
332
  orderMatters: boolean;
333
333
  padding: boolean;
334
334
  };
335
+ export type PerseusMatrixWidgetAnswers = ReadonlyArray<ReadonlyArray<number>>;
335
336
  export type PerseusMatrixWidgetOptions = {
336
337
  prefix: string;
337
338
  suffix: string;
338
- answers: ReadonlyArray<ReadonlyArray<number>>;
339
+ answers: PerseusMatrixWidgetAnswers;
339
340
  cursorPosition: ReadonlyArray<number>;
340
341
  matrixBoardSize: ReadonlyArray<number>;
341
342
  static: boolean;
@@ -385,7 +386,7 @@ export type PerseusNumberLineWidgetOptions = {
385
386
  snapDivisions: number;
386
387
  tickStep: number | null | undefined;
387
388
  correctRel: string | null | undefined;
388
- correctX: number | null | undefined;
389
+ correctX: number;
389
390
  initialX: number | null | undefined;
390
391
  showTooltip?: boolean;
391
392
  static: boolean;
@@ -3,8 +3,8 @@ import InteractionTracker from "./interaction-tracker";
3
3
  import TranslationLinter from "./translation-linter";
4
4
  import WidgetContainer from "./widget-container";
5
5
  import type { DependenciesContext } from "./dependencies";
6
- import type { PerseusRenderer, PerseusWidgetOptions } from "./perseus-types";
7
- import type { APIOptions, APIOptionsWithDefaults, FilterCriterion, FocusPath, PerseusScore, WidgetInfo, WidgetProps } from "./types";
6
+ import type { PerseusRenderer, PerseusWidget, PerseusWidgetOptions } from "./perseus-types";
7
+ import type { APIOptions, APIOptionsWithDefaults, FilterCriterion, FocusPath, PerseusScore, WidgetProps } from "./types";
8
8
  import type { LinterContextProps } from "@khanacademy/perseus-linter";
9
9
  import "./styles/perseus-renderer.less";
10
10
  type WidgetState = {
@@ -64,7 +64,7 @@ type Props = Partial<React.ContextType<typeof DependenciesContext>> & {
64
64
  type State = {
65
65
  translationLintErrors: ReadonlyArray<string>;
66
66
  widgetInfo: Readonly<{
67
- [id: string]: WidgetInfo | null | undefined;
67
+ [id: string]: PerseusWidget | null | undefined;
68
68
  }>;
69
69
  widgetProps: Readonly<{
70
70
  [id: string]: any | null | undefined;
@@ -115,13 +115,13 @@ declare class Renderer extends React.Component<Props, State> {
115
115
  widgetProps: State["widgetProps"];
116
116
  };
117
117
  _getAllWidgetsInfo: (props: Props) => {
118
- [key: string]: WidgetInfo;
118
+ [key: string]: PerseusWidget;
119
119
  };
120
120
  _getAllWidgetsStartProps: (allWidgetInfo: {
121
- [key: string]: WidgetInfo;
121
+ [key: string]: PerseusWidget;
122
122
  }, props: Props) => any;
123
123
  _getDefaultWidgetInfo: (widgetId: string) => any;
124
- _getWidgetInfo: (widgetId: string) => WidgetInfo;
124
+ _getWidgetInfo: (widgetId: string) => PerseusWidget;
125
125
  renderWidget: (impliedType: string, id: string, state: WidgetState) => null | React.ReactNode;
126
126
  getWidgetProps: (id: string) => WidgetProps<any, PerseusWidgetOptions>;
127
127
  /**
@@ -9,6 +9,7 @@ import * as PerseusLinter from "@khanacademy/perseus-linter";
9
9
  */
10
10
  import * as React from "react";
11
11
  import Renderer from "./renderer";
12
+ import type { PerseusItem } from "./perseus-types";
12
13
  import type { APIOptions, FocusPath, PerseusDependenciesV2 } from "./types";
13
14
  import type { KeypadAPI } from "@khanacademy/math-input";
14
15
  import type { KeypadContextRendererInterface, RendererInterface, KEScore } from "@khanacademy/perseus-core";
@@ -16,10 +17,7 @@ import type { LinterContextProps } from "@khanacademy/perseus-linter";
16
17
  type OwnProps = {
17
18
  apiOptions: APIOptions;
18
19
  hintsVisible?: number;
19
- item: {
20
- hints: ReadonlyArray<any>;
21
- question: any;
22
- };
20
+ item: PerseusItem;
23
21
  linterContext: LinterContextProps;
24
22
  problemNum?: number;
25
23
  reviewMode?: boolean;
package/dist/strings.js CHANGED
@@ -121,6 +121,7 @@ module.exports = [
121
121
  i18n._("Skip to %(title)s", {}),
122
122
  i18n._("Something went wrong.", {}),
123
123
  i18n._("Sorry, I don't understand that!", {}),
124
+ i18n._("Sorry, this part of the question is no longer available. 😅 Don't worry, you won't be graded on this part. Keep going!", {}),
124
125
  i18n._("Switch direction", {}),
125
126
  i18n._("Tap each dot on the image to select all answers that apply.", {}),
126
127
  i18n._("Tap each dot on the image to select an answer.", {}),
@@ -130,7 +131,6 @@ module.exports = [
130
131
  i18n._("This controls the proportion or percentage that will be used in your simulation.", {}),
131
132
  i18n._("This controls the sample size that will be used in your simulation. For example, if you set this to 100, then for each trial, responses from 100 participants will be simulated.", {}),
132
133
  i18n._("This is the number of trials used in the simulation. For example, if set to 50, then the survey will be conducted 50 times.", {}),
133
- i18n._("This part of the question is no-longer available. You will not be graded on this part.", {}),
134
134
  // I18N: As in the command, "Translate the polygon"
135
135
  i18n._("Translate", {}),
136
136
  i18n._("translation", {}),
package/dist/types.d.ts CHANGED
@@ -213,7 +213,15 @@ export type WidgetExports<T extends React.ComponentType<any> = React.ComponentTy
213
213
  displayName: string;
214
214
  getWidget?: () => T;
215
215
  accessible?: boolean | ((props: any) => boolean);
216
+ /** Supresses widget from showing up in the dropdown in the content editor */
216
217
  hidden?: boolean;
218
+ /**
219
+ The widget version. Any time the _major_ version changes, the widget
220
+ should provide a new entry in the propUpgrades map to migrate from the
221
+ older version to the current (new) version. Minor version changes must
222
+ be backwards compatible with previous minor versions widget options.
223
+ This key defaults to `{major: 0, minor: 0}` if not provided.
224
+ */
217
225
  version?: Version;
218
226
  supportedAlignments?: ReadonlyArray<Alignment>;
219
227
  defaultAlignment?: Alignment;
@@ -221,15 +229,24 @@ export type WidgetExports<T extends React.ComponentType<any> = React.ComponentTy
221
229
  isLintable?: boolean;
222
230
  tracking?: Tracking;
223
231
  traverseChildWidgets?: any;
232
+ /** transforms the widget options to the props used to render the widget */
224
233
  transform?: WidgetTransform;
234
+ /** transforms the widget options to the props used to render the widget for
235
+ static renders */
225
236
  staticTransform?: WidgetTransform;
237
+ /**
238
+ A map of major version numbers (as a string, eg "1") to a function that
239
+ migrates from the _previous_ major version.
240
+ Example:
241
+ propUpgrades: {'1': (options) => ({...options})}
242
+ would migrate from major version 0 to 1.
243
+ */
226
244
  propUpgrades?: {
227
245
  [key: string]: (arg1: any) => any;
228
246
  };
229
247
  widget: T;
230
248
  }>;
231
- export type WidgetInfo = PerseusWidget;
232
- export type FilterCriterion = string | ((id: string, widgetInfo: WidgetInfo, widget?: Widget | null | undefined) => boolean);
249
+ export type FilterCriterion = string | ((id: string, widgetInfo: PerseusWidget, widget?: Widget | null | undefined) => boolean);
233
250
  export type WidgetProps<RenderProps, Rubric, TrackingExtraArgs = Empty> = RenderProps & {
234
251
  widgetId: string;
235
252
  alignment: string | null | undefined;
@@ -0,0 +1,21 @@
1
+ import type { GraphBounds } from "./graph-bounds";
2
+ import type { Coord } from "../interactive2/types";
3
+ interface Raphael {
4
+ setSize(width: number, height: number): any;
5
+ }
6
+ export declare class DrawingTransform {
7
+ raphael: Raphael;
8
+ xScale: number;
9
+ yScale: number;
10
+ bounds: GraphBounds;
11
+ constructor(raphael: Raphael, initialScale: [number, number], bounds: GraphBounds);
12
+ scaleVector: (point: number | Coord) => any;
13
+ scalePoint: (point: number | Coord) => Coord;
14
+ unscalePoint: (point: number | Coord) => any;
15
+ unscaleVector: (point: number | Coord) => any;
16
+ setScale: (scale: number | Coord) => void;
17
+ canvasDimensions: () => Coord;
18
+ pixelsPerUnitX: () => number;
19
+ pixelsPerUnitY: () => number;
20
+ }
21
+ export {};
@@ -0,0 +1,26 @@
1
+ import type { PerseusRenderer } from "../perseus-types";
2
+ /**
3
+ * This function extracts the answers from the widgets.
4
+ *
5
+ * For each widget type, we first check to make sure the path to the answer exists,
6
+ * then we extract the answer and add it to the list of answers.
7
+ *
8
+ * A list is returned because some widgets, like multi-select radio widgets and groups
9
+ * can have multiple answers.
10
+ *
11
+ * @param {PerseusRenderer["widgets"]} widgets
12
+ * @returns a list of strings that are the answers to the widgets
13
+ */
14
+ declare function getAnswersFromWidgets(widgets: PerseusRenderer["widgets"]): ReadonlyArray<string>;
15
+ /**
16
+ * Inject a string equivalent of the widgets into the content.
17
+ *
18
+ * Content may contain Perseus widgets, that looks like this: '[[☃ Radio 1]]'.
19
+ * This function replaces those widgets with its equivalent string.
20
+ *
21
+ * @param {string} content
22
+ * @param {PerseusRenderer["widgets"]} widgets
23
+ * @returns
24
+ */
25
+ declare function injectWidgets(content: string, widgets: PerseusRenderer["widgets"]): string;
26
+ export { getAnswersFromWidgets, injectWidgets };
@@ -0,0 +1,9 @@
1
+ export declare class GraphBounds {
2
+ readonly xMin: number;
3
+ readonly xMax: number;
4
+ readonly yMin: number;
5
+ readonly yMax: number;
6
+ constructor(xRange: [number, number], yRange: [number, number]);
7
+ width(): number;
8
+ height(): number;
9
+ }
@@ -1,2 +1,4 @@
1
+ import type { Coord } from "../interactive2/types";
2
+ export declare function polar(r: number | Coord, th: number): number[];
1
3
  declare const GraphUtils: any;
2
4
  export default GraphUtils;
@@ -0,0 +1 @@
1
+ export type Interval = [number, number];
@@ -0,0 +1,10 @@
1
+ import type { PerseusItem } from "../perseus-types";
2
+ /**
3
+ * Helper to parse Perseus JSON
4
+ * Why not just use JSON.parse? We want:
5
+ * - To make sure types are correct
6
+ * - To give us a central place to validate/transform output if needed
7
+ * @param {string} input - the stringified Perseus JSON
8
+ * @returns {PerseusItem} the parsed PerseusItem object
9
+ */
10
+ export default function parsePerseusJSON(input: string): PerseusItem;
@@ -1,6 +1,4 @@
1
1
  declare const _default: {
2
- processMath: (elem: HTMLElement, text: string, force?: boolean, callback?: () => unknown) => Promise<void>;
3
- cleanupMath: (elem: HTMLElement) => HTMLElement;
4
- retrieveMathFormula: (elem: HTMLElement) => any;
2
+ processMath: (elem: HTMLElement, text: string | number, force?: boolean, callback?: () => unknown) => Promise<void>;
5
3
  };
6
4
  export default _default;
@@ -1,9 +1,9 @@
1
1
  import React from "react";
2
2
  import type { PerseusScore } from "../../types";
3
- type AutoCorrectProps = any;
3
+ type Props = any;
4
4
  type Rubric = any;
5
5
  type UserInput = Empty;
6
- declare class AutoCorrect extends React.Component<AutoCorrectProps> {
6
+ declare class DeprecatedStandin extends React.Component<Props> {
7
7
  static validate(userInput: UserInput, rubric: Rubric): PerseusScore;
8
8
  getUserInput: () => UserInput;
9
9
  simpleValidate: (arg1: Rubric) => PerseusScore;
@@ -12,7 +12,7 @@ declare class AutoCorrect extends React.Component<AutoCorrectProps> {
12
12
  declare const _default: Readonly<{
13
13
  name: string;
14
14
  displayName: string;
15
- getWidget?: (() => typeof AutoCorrect) | undefined;
15
+ getWidget?: (() => typeof DeprecatedStandin) | undefined;
16
16
  accessible?: boolean | ((props: any) => boolean) | undefined;
17
17
  hidden?: boolean | undefined;
18
18
  version?: import("../../types").Version | undefined;
@@ -27,6 +27,6 @@ declare const _default: Readonly<{
27
27
  propUpgrades?: {
28
28
  [key: string]: (arg1: any) => any;
29
29
  } | undefined;
30
- widget: typeof AutoCorrect;
30
+ widget: typeof DeprecatedStandin;
31
31
  }>;
32
32
  export default _default;
@@ -2,8 +2,8 @@ import * as React from "react";
2
2
  import type { ParseState } from "./passage/passage-markdown";
3
3
  import type { SerializedHighlightSet } from "../components/highlighting/types";
4
4
  import type { ChangeableProps } from "../mixins/changeable";
5
- import type { PerseusPassageWidgetOptions } from "../perseus-types";
6
- import type { PerseusScore, WidgetInfo, WidgetProps } from "../types";
5
+ import type { PerseusPassageWidgetOptions, PerseusWidget } from "../perseus-types";
6
+ import type { PerseusScore, WidgetProps } from "../types";
7
7
  import type { SingleASTNode } from "@khanacademy/simple-markdown";
8
8
  export declare class LineHeightMeasurer extends React.Component<Record<any, any>> {
9
9
  _line: HTMLDivElement | null | undefined;
@@ -18,7 +18,7 @@ type RenderProps = {
18
18
  footnotes: PerseusPassageWidgetOptions["footnotes"];
19
19
  showLineNumbers: PerseusPassageWidgetOptions["showLineNumbers"];
20
20
  };
21
- type FindWidgetsCallback = (id: string, widgetInfo: WidgetInfo) => boolean;
21
+ type FindWidgetsCallback = (id: string, widgetInfo: PerseusWidget) => boolean;
22
22
  type PassageProps = ChangeableProps & WidgetProps<RenderProps, Rubric> & {
23
23
  findWidgets: (arg1: FindWidgetsCallback) => ReadonlyArray<Passage>;
24
24
  highlights: SerializedHighlightSet;
package/dist/widgets.d.ts CHANGED
@@ -1,4 +1,5 @@
1
- import type { Alignment, Tracking, Version, WidgetExports, WidgetInfo, WidgetTransform } from "./types";
1
+ import type { PerseusWidget } from "./perseus-types";
2
+ import type { Alignment, Tracking, Version, WidgetExports, WidgetTransform } from "./types";
2
3
  import type * as React from "react";
3
4
  type Editor = any;
4
5
  export declare const registerWidget: (name: string, widget: WidgetExports) => void;
@@ -13,19 +14,28 @@ export declare const registerWidgets: (widgets: ReadonlyArray<WidgetExports>) =>
13
14
  */
14
15
  export declare const replaceWidget: (name: string, replacementName: string) => void;
15
16
  export declare const registerEditors: (editorsToRegister: ReadonlyArray<Editor>) => void;
17
+ /**
18
+ *
19
+ * @param name - the widget that you are trying to replace
20
+ * @param replacementName - the name of the widget that takes its place
21
+ *
22
+ * e.g. replaceEditor("transformer", "always-correct") will make it so the
23
+ * transformer widget is replaced by the always correct widget
24
+ */
25
+ export declare const replaceEditor: (name: string, replacementName: string) => void;
16
26
  export declare const getWidget: (name: string) => React.ComponentType<any> | null | undefined;
17
27
  export declare const getEditor: (name: string) => Editor | null | undefined;
18
28
  export declare const getTransform: (name: string) => WidgetTransform | null | undefined;
19
- export declare const getVersion: (name: string) => Version | null | undefined;
29
+ export declare const getVersion: (name: string) => Version | undefined;
20
30
  export declare const getVersionVector: () => {
21
31
  [key: string]: Version;
22
32
  };
23
33
  export declare const getPublicWidgets: () => ReadonlyArray<WidgetExports>;
24
- export declare const isAccessible: (widgetInfo: WidgetInfo) => boolean;
34
+ export declare const isAccessible: (widgetInfo: PerseusWidget) => boolean;
25
35
  export declare const getAllWidgetTypes: () => ReadonlyArray<string>;
26
- export declare const upgradeWidgetInfoToLatestVersion: (oldWidgetInfo: WidgetInfo) => WidgetInfo;
27
- export declare const getRendererPropsForWidgetInfo: (widgetInfo: WidgetInfo, problemNum?: number) => any;
28
- export declare const traverseChildWidgets: (widgetInfo: WidgetInfo, traverseRenderer: any) => WidgetInfo;
36
+ export declare const upgradeWidgetInfoToLatestVersion: (oldWidgetInfo: PerseusWidget) => PerseusWidget;
37
+ export declare const getRendererPropsForWidgetInfo: (widgetInfo: PerseusWidget, problemNum?: number) => PerseusWidget;
38
+ export declare const traverseChildWidgets: (widgetInfo: PerseusWidget, traverseRenderer: any) => PerseusWidget;
29
39
  /**
30
40
  * Handling for the optional alignments for widgets
31
41
  * See widget-container.jsx for details on how alignments are implemented.
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "description": "Core Perseus API (includes renderers and widgets)",
4
4
  "author": "Khan Academy",
5
5
  "license": "MIT",
6
- "version": "17.8.0",
6
+ "version": "18.0.1",
7
7
  "publishConfig": {
8
8
  "access": "public"
9
9
  },
@@ -24,8 +24,7 @@
24
24
  "dependencies": {
25
25
  "@khanacademy/kas": "^0.3.7",
26
26
  "@khanacademy/kmath": "^0.1.8",
27
- "@khanacademy/math-input": "^16.5.0",
28
- "@khanacademy/mathjax-renderer": "git+ssh://git@github.com:Khan/mathjax-renderer.git#v1.5.0",
27
+ "@khanacademy/math-input": "^16.5.1",
29
28
  "@khanacademy/perseus-core": "1.4.1",
30
29
  "@khanacademy/perseus-linter": "^0.3.10",
31
30
  "@khanacademy/pure-markdown": "^0.2.13",
@@ -33,23 +32,24 @@
33
32
  "@khanacademy/wonder-blocks-banner": "^3.0.33"
34
33
  },
35
34
  "devDependencies": {
35
+ "@khanacademy/mathjax-renderer": "git+ssh://git@github.com:Khan/mathjax-renderer.git#v1.5.1",
36
36
  "@khanacademy/wonder-blocks-button": "^6.2.5",
37
37
  "@khanacademy/wonder-blocks-clickable": "^4.0.12",
38
38
  "@khanacademy/wonder-blocks-color": "^3.0.0",
39
39
  "@khanacademy/wonder-blocks-core": "^6.3.1",
40
40
  "@khanacademy/wonder-blocks-data": "^13.0.6",
41
- "@khanacademy/wonder-blocks-dropdown": "^5.1.0",
41
+ "@khanacademy/wonder-blocks-dropdown": "^5.1.2",
42
42
  "@khanacademy/wonder-blocks-form": "^4.3.19",
43
43
  "@khanacademy/wonder-blocks-i18n": "^2.0.2",
44
44
  "@khanacademy/wonder-blocks-layout": "^2.0.25",
45
45
  "@khanacademy/wonder-blocks-link": "^6.0.5",
46
- "@khanacademy/wonder-blocks-modal": "^4.2.0",
47
- "@khanacademy/wonder-blocks-pill": "^1.0.15",
48
- "@khanacademy/wonder-blocks-popover": "^3.0.22",
46
+ "@khanacademy/wonder-blocks-modal": "^4.2.1",
47
+ "@khanacademy/wonder-blocks-pill": "^2.0.0",
48
+ "@khanacademy/wonder-blocks-popover": "^3.1.0",
49
49
  "@khanacademy/wonder-blocks-progress-spinner": "^2.0.25",
50
50
  "@khanacademy/wonder-blocks-spacing": "^4.0.1",
51
- "@khanacademy/wonder-blocks-switch": "^1.1.9",
52
- "@khanacademy/wonder-blocks-tooltip": "^2.1.24",
51
+ "@khanacademy/wonder-blocks-switch": "^1.1.10",
52
+ "@khanacademy/wonder-blocks-tooltip": "^2.1.25",
53
53
  "@khanacademy/wonder-blocks-typography": "^2.1.10",
54
54
  "@khanacademy/wonder-stuff-core": "^1.5.1",
55
55
  "@phosphor-icons/core": "^2.0.2",