@khanacademy/perseus-core 4.0.0 → 5.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
@@ -1,5 +1,6 @@
1
1
  import _ from 'underscore';
2
2
  import _extends from '@babel/runtime/helpers/extends';
3
+ import * as KAS from '@khanacademy/kas';
3
4
  import _objectWithoutPropertiesLoose from '@babel/runtime/helpers/objectWithoutPropertiesLoose';
4
5
  import { seededRNG as seededRNG$1, shuffle as shuffle$1 } from '@khanacademy/perseus-core';
5
6
 
@@ -1081,6 +1082,76 @@ const parseExplanationWidget = parseWidget(constant("explanation"), object({
1081
1082
  static: defaulted(boolean, () => false)
1082
1083
  }));
1083
1084
 
1085
+ const KeypadKeys = ["PLUS", "MINUS", "NEGATIVE", "TIMES", "DIVIDE", "DECIMAL", "PERIOD", "PERCENT", "CDOT", "EQUAL", "NEQ", "GT", "LT", "GEQ", "LEQ",
1086
+ // mobile native only
1087
+ "FRAC_INCLUSIVE",
1088
+ // mobile native only
1089
+ "FRAC_EXCLUSIVE",
1090
+ // mobile native only
1091
+ "FRAC", "EXP", "EXP_2", "EXP_3", "SQRT", "CUBE_ROOT", "RADICAL", "LEFT_PAREN", "RIGHT_PAREN", "LN", "LOG", "LOG_N", "SIN", "COS",
1092
+ // TODO(charlie): Add in additional Greek letters.,
1093
+ "TAN", "PI", "THETA", "UP", "RIGHT", "DOWN", "LEFT", "BACKSPACE", "DISMISS", "JUMP_OUT_PARENTHESES", "JUMP_OUT_EXPONENT", "JUMP_OUT_BASE", "JUMP_INTO_NUMERATOR", "JUMP_OUT_NUMERATOR", "JUMP_OUT_DENOMINATOR",
1094
+ // Multi-functional keys.
1095
+ "NUM_0", "NUM_1", "NUM_2", "NUM_3", "NUM_4", "NUM_5", "NUM_6", "NUM_7", "NUM_8", "NUM_9", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"];
1096
+
1097
+ // Used by KeypadContext to pass around a renderer reference
1098
+
1099
+ /**
1100
+ * Scrape the answer forms for any variables or contants (like Pi)
1101
+ * that need to be included as keys on the keypad.
1102
+ */
1103
+ function deriveExtraKeys(widgetOptions) {
1104
+ if (widgetOptions.extraKeys) {
1105
+ return widgetOptions.extraKeys;
1106
+ }
1107
+
1108
+ // If there are no extra symbols available, we include Pi anyway, so
1109
+ // that the "extra symbols" button doesn't appear empty.
1110
+ const defaultKeys = ["PI"];
1111
+ if (widgetOptions.answerForms == null) {
1112
+ return defaultKeys;
1113
+ }
1114
+
1115
+ // Extract any and all variables and constants from the answer forms.
1116
+ const uniqueExtraVariables = {};
1117
+ const uniqueExtraConstants = {};
1118
+ for (const answerForm of widgetOptions.answerForms) {
1119
+ const maybeExpr = KAS.parse(answerForm.value, widgetOptions);
1120
+ if (maybeExpr.parsed) {
1121
+ const expr = maybeExpr.expr;
1122
+
1123
+ // The keypad expects Greek letters to be capitalized (e.g., it
1124
+ // requires `PI` instead of `pi`). Right now, it only supports Pi
1125
+ // and Theta, so we special-case.
1126
+ const isGreek = symbol => symbol === "pi" || symbol === "theta";
1127
+ const toKey = symbol => isGreek(symbol) ? symbol.toUpperCase() : symbol;
1128
+ const isKey = key => KeypadKeys.includes(key);
1129
+ for (const variable of expr.getVars()) {
1130
+ const maybeKey = toKey(variable);
1131
+ if (isKey(maybeKey)) {
1132
+ uniqueExtraVariables[maybeKey] = true;
1133
+ }
1134
+ }
1135
+ for (const constant of expr.getConsts()) {
1136
+ const maybeKey = toKey(constant);
1137
+ if (isKey(maybeKey)) {
1138
+ uniqueExtraConstants[maybeKey] = true;
1139
+ }
1140
+ }
1141
+ }
1142
+ }
1143
+
1144
+ // TODO(charlie): Alert the keypad as to which of these symbols should be
1145
+ // treated as functions.
1146
+ const extraVariables = Object.keys(uniqueExtraVariables).sort();
1147
+ const extraConstants = Object.keys(uniqueExtraConstants).sort();
1148
+ const extraKeys = [...extraVariables, ...extraConstants];
1149
+ if (!extraKeys.length) {
1150
+ return defaultKeys;
1151
+ }
1152
+ return extraKeys;
1153
+ }
1154
+
1084
1155
  // Given a function, creates a PartialParser that converts one type to another
1085
1156
  // using that function. The returned parser never fails.
1086
1157
  function convert(f) {
@@ -1182,11 +1253,25 @@ function removeInvalidAnswerForms(possiblyInvalid) {
1182
1253
  }
1183
1254
  return valid;
1184
1255
  }
1185
- const version1 = object({
1256
+ const version2$1 = object({
1257
+ major: constant(2),
1258
+ minor: number
1259
+ });
1260
+ const parseExpressionWidgetV2 = parseWidgetWithVersion(version2$1, constant("expression"), object({
1261
+ answerForms: pipeParsers(array(parsePossiblyInvalidAnswerForm)).then(convert(removeInvalidAnswerForms)).parser,
1262
+ functions: array(string),
1263
+ times: boolean,
1264
+ visibleLabel: optional(string),
1265
+ ariaLabel: optional(string),
1266
+ buttonSets: parseLegacyButtonSets,
1267
+ buttonsVisible: optional(enumeration("always", "never", "focused")),
1268
+ extraKeys: array(enumeration(...KeypadKeys))
1269
+ }));
1270
+ const version1$1 = object({
1186
1271
  major: constant(1),
1187
1272
  minor: number
1188
1273
  });
1189
- const parseExpressionWidgetV1 = parseWidgetWithVersion(version1, constant("expression"), object({
1274
+ const parseExpressionWidgetV1 = parseWidgetWithVersion(version1$1, constant("expression"), object({
1190
1275
  answerForms: pipeParsers(array(parsePossiblyInvalidAnswerForm)).then(convert(removeInvalidAnswerForms)).parser,
1191
1276
  functions: array(string),
1192
1277
  times: boolean,
@@ -1195,11 +1280,32 @@ const parseExpressionWidgetV1 = parseWidgetWithVersion(version1, constant("expre
1195
1280
  buttonSets: parseLegacyButtonSets,
1196
1281
  buttonsVisible: optional(enumeration("always", "never", "focused"))
1197
1282
  }));
1198
- const version0 = optional(object({
1283
+ function migrateV1ToV2$1(widget) {
1284
+ const {
1285
+ options
1286
+ } = widget;
1287
+ return _extends({}, widget, {
1288
+ version: {
1289
+ major: 2,
1290
+ minor: 0
1291
+ },
1292
+ options: {
1293
+ times: options.times,
1294
+ buttonSets: options.buttonSets,
1295
+ functions: options.functions,
1296
+ buttonsVisible: options.buttonsVisible,
1297
+ visibleLabel: options.visibleLabel,
1298
+ ariaLabel: options.ariaLabel,
1299
+ answerForms: options.answerForms,
1300
+ extraKeys: deriveExtraKeys(options)
1301
+ }
1302
+ });
1303
+ }
1304
+ const version0$1 = optional(object({
1199
1305
  major: constant(0),
1200
1306
  minor: number
1201
1307
  }));
1202
- const parseExpressionWidgetV0 = parseWidgetWithVersion(version0, constant("expression"), object({
1308
+ const parseExpressionWidgetV0 = parseWidgetWithVersion(version0$1, constant("expression"), object({
1203
1309
  functions: array(string),
1204
1310
  times: boolean,
1205
1311
  visibleLabel: optional(string),
@@ -1210,7 +1316,7 @@ const parseExpressionWidgetV0 = parseWidgetWithVersion(version0, constant("expre
1210
1316
  buttonSets: parseLegacyButtonSets,
1211
1317
  buttonsVisible: optional(enumeration("always", "never", "focused"))
1212
1318
  }));
1213
- function migrateV0ToV1(widget) {
1319
+ function migrateV0ToV1$1(widget) {
1214
1320
  const {
1215
1321
  options
1216
1322
  } = widget;
@@ -1235,7 +1341,7 @@ function migrateV0ToV1(widget) {
1235
1341
  }
1236
1342
  });
1237
1343
  }
1238
- const parseExpressionWidget = versionedWidgetOptions(1, parseExpressionWidgetV1).withMigrationFrom(0, parseExpressionWidgetV0, migrateV0ToV1).parser;
1344
+ const parseExpressionWidget = versionedWidgetOptions(2, parseExpressionWidgetV2).withMigrationFrom(1, parseExpressionWidgetV1, migrateV1ToV2$1).withMigrationFrom(0, parseExpressionWidgetV0, migrateV0ToV1$1).parser;
1239
1345
 
1240
1346
  const falseToNull = pipeParsers(constant(false)).then(convert(() => null)).parser;
1241
1347
  const parseGradedGroupWidgetOptions = object({
@@ -2239,7 +2345,84 @@ const parsePythonProgramWidget = parseWidget(constant("python-program"), object(
2239
2345
  height: number
2240
2346
  }));
2241
2347
 
2242
- const parseRadioWidget = parseWidget(constant("radio"), object({
2348
+ const _excluded$a = ["noneOfTheAbove"];
2349
+ const currentVersion$3 = {
2350
+ major: 2,
2351
+ minor: 0
2352
+ };
2353
+ function deriveNumCorrect(options) {
2354
+ const {
2355
+ choices,
2356
+ numCorrect
2357
+ } = options;
2358
+ return numCorrect != null ? numCorrect : choices.filter(c => c.correct).length;
2359
+ }
2360
+ const widgetOptionsUpgrades$2 = {
2361
+ "2": v1props => {
2362
+ const upgraded = _extends({}, v1props, {
2363
+ numCorrect: deriveNumCorrect(v1props)
2364
+ });
2365
+ return upgraded;
2366
+ },
2367
+ "1": v0props => {
2368
+ const {
2369
+ noneOfTheAbove
2370
+ } = v0props,
2371
+ rest = _objectWithoutPropertiesLoose(v0props, _excluded$a);
2372
+ if (noneOfTheAbove) {
2373
+ throw new Error("radio widget v0 no longer supports auto noneOfTheAbove");
2374
+ }
2375
+ return _extends({}, rest, {
2376
+ hasNoneOfTheAbove: false
2377
+ });
2378
+ }
2379
+ };
2380
+ const defaultWidgetOptions$v = {
2381
+ choices: [{}, {}, {}, {}],
2382
+ displayCount: null,
2383
+ randomize: false,
2384
+ hasNoneOfTheAbove: false,
2385
+ multipleSelect: false,
2386
+ countChoices: false,
2387
+ deselectEnabled: false
2388
+ };
2389
+
2390
+ const _excluded$9 = ["noneOfTheAbove"];
2391
+ const version2 = optional(object({
2392
+ major: constant(2),
2393
+ minor: number
2394
+ }));
2395
+ const parseRadioWidgetV2 = parseWidgetWithVersion(version2, constant("radio"), object({
2396
+ numCorrect: optional(number),
2397
+ choices: array(object({
2398
+ content: defaulted(string, () => ""),
2399
+ clue: optional(string),
2400
+ correct: optional(boolean),
2401
+ isNoneOfTheAbove: optional(boolean),
2402
+ // deprecated
2403
+ // There is an import cycle between radio-widget.ts and
2404
+ // widgets-map.ts. The anonymous function below ensures that we
2405
+ // don't refer to parseWidgetsMap before it's defined.
2406
+ widgets: optional((rawVal, ctx) => parseWidgetsMap(rawVal, ctx))
2407
+ })),
2408
+ hasNoneOfTheAbove: optional(boolean),
2409
+ countChoices: optional(boolean),
2410
+ randomize: optional(boolean),
2411
+ multipleSelect: optional(boolean),
2412
+ deselectEnabled: optional(boolean),
2413
+ // deprecated
2414
+ onePerLine: optional(boolean),
2415
+ // deprecated
2416
+ displayCount: optional(any),
2417
+ // v0 props
2418
+ // `noneOfTheAbove` is still in use (but only set to `false`).
2419
+ noneOfTheAbove: optional(constant(false))
2420
+ }));
2421
+ const version1 = optional(object({
2422
+ major: constant(1),
2423
+ minor: number
2424
+ }));
2425
+ const parseRadioWidgetV1 = parseWidgetWithVersion(version1, constant("radio"), object({
2243
2426
  choices: array(object({
2244
2427
  content: defaulted(string, () => ""),
2245
2428
  clue: optional(string),
@@ -2264,6 +2447,65 @@ const parseRadioWidget = parseWidget(constant("radio"), object({
2264
2447
  // `noneOfTheAbove` is still in use (but only set to `false`).
2265
2448
  noneOfTheAbove: optional(constant(false))
2266
2449
  }));
2450
+ function migrateV1ToV2(widget) {
2451
+ const {
2452
+ options
2453
+ } = widget;
2454
+ return _extends({}, widget, {
2455
+ version: {
2456
+ major: 2,
2457
+ minor: 0
2458
+ },
2459
+ options: _extends({}, options, {
2460
+ numCorrect: deriveNumCorrect(options)
2461
+ })
2462
+ });
2463
+ }
2464
+ const version0 = optional(object({
2465
+ major: constant(0),
2466
+ minor: number
2467
+ }));
2468
+ const parseRadioWidgetV0 = parseWidgetWithVersion(version0, constant("radio"), object({
2469
+ choices: array(object({
2470
+ content: defaulted(string, () => ""),
2471
+ clue: optional(string),
2472
+ correct: optional(boolean),
2473
+ isNoneOfTheAbove: optional(boolean),
2474
+ // deprecated
2475
+ // There is an import cycle between radio-widget.ts and
2476
+ // widgets-map.ts. The anonymous function below ensures that we
2477
+ // don't refer to parseWidgetsMap before it's defined.
2478
+ widgets: optional((rawVal, ctx) => parseWidgetsMap(rawVal, ctx))
2479
+ })),
2480
+ hasNoneOfTheAbove: optional(boolean),
2481
+ countChoices: optional(boolean),
2482
+ randomize: optional(boolean),
2483
+ multipleSelect: optional(boolean),
2484
+ deselectEnabled: optional(boolean),
2485
+ // deprecated
2486
+ onePerLine: optional(boolean),
2487
+ // deprecated
2488
+ displayCount: optional(any),
2489
+ // v0 props
2490
+ // `noneOfTheAbove` is still in use (but only set to `false`).
2491
+ noneOfTheAbove: optional(constant(false))
2492
+ }));
2493
+ function migrateV0ToV1(widget) {
2494
+ const {
2495
+ options
2496
+ } = widget;
2497
+ const rest = _objectWithoutPropertiesLoose(options, _excluded$9);
2498
+ return _extends({}, widget, {
2499
+ version: {
2500
+ major: 1,
2501
+ minor: 0
2502
+ },
2503
+ options: _extends({}, rest, {
2504
+ hasNoneOfTheAbove: false
2505
+ })
2506
+ });
2507
+ }
2508
+ const parseRadioWidget = versionedWidgetOptions(2, parseRadioWidgetV2).withMigrationFrom(1, parseRadioWidgetV1, migrateV1ToV2).withMigrationFrom(0, parseRadioWidgetV0, migrateV0ToV1).parser;
2267
2509
 
2268
2510
  const parseSorterWidget = parseWidget(constant("sorter"), object({
2269
2511
  correct: array(string),
@@ -2602,7 +2844,7 @@ const addLibraryVersionToPerseusDebug = (libraryName, libraryVersion) => {
2602
2844
 
2603
2845
  // This file is processed by a Rollup plugin (replace) to inject the production
2604
2846
  const libName = "@khanacademy/perseus-core";
2605
- const libVersion = "4.0.0";
2847
+ const libVersion = "5.0.0";
2606
2848
  addLibraryVersionToPerseusDebug(libName, libVersion);
2607
2849
 
2608
2850
  /**
@@ -2719,7 +2961,7 @@ function getCategorizerPublicWidgetOptions(options) {
2719
2961
  };
2720
2962
  }
2721
2963
 
2722
- const defaultWidgetOptions$v = {
2964
+ const defaultWidgetOptions$u = {
2723
2965
  items: [],
2724
2966
  categories: [],
2725
2967
  values: [],
@@ -2727,7 +2969,7 @@ const defaultWidgetOptions$v = {
2727
2969
  };
2728
2970
  const categorizerWidgetLogic = {
2729
2971
  name: "categorizer",
2730
- defaultWidgetOptions: defaultWidgetOptions$v,
2972
+ defaultWidgetOptions: defaultWidgetOptions$u,
2731
2973
  getPublicWidgetOptions: getCategorizerPublicWidgetOptions
2732
2974
  };
2733
2975
 
@@ -2736,7 +2978,7 @@ function getCSProgramPublicWidgetOptions(options) {
2736
2978
  }
2737
2979
 
2738
2980
  const DEFAULT_HEIGHT = 400;
2739
- const defaultWidgetOptions$u = {
2981
+ const defaultWidgetOptions$t = {
2740
2982
  programID: "",
2741
2983
  programType: null,
2742
2984
  settings: [{
@@ -2749,18 +2991,18 @@ const defaultWidgetOptions$u = {
2749
2991
  };
2750
2992
  const csProgramWidgetLogic = {
2751
2993
  name: "cs-program",
2752
- defaultWidgetOptions: defaultWidgetOptions$u,
2994
+ defaultWidgetOptions: defaultWidgetOptions$t,
2753
2995
  supportedAlignments: ["block", "full-width"],
2754
2996
  getPublicWidgetOptions: getCSProgramPublicWidgetOptions
2755
2997
  };
2756
2998
 
2757
- const defaultWidgetOptions$t = {
2999
+ const defaultWidgetOptions$s = {
2758
3000
  togglePrompt: "",
2759
3001
  definition: ""
2760
3002
  };
2761
3003
  const definitionWidgetLogic = {
2762
3004
  name: "definition",
2763
- defaultWidgetOptions: defaultWidgetOptions$t,
3005
+ defaultWidgetOptions: defaultWidgetOptions$s,
2764
3006
  defaultAlignment: "inline"
2765
3007
  };
2766
3008
 
@@ -2785,7 +3027,7 @@ function getDropdownPublicWidgetOptions(options) {
2785
3027
  };
2786
3028
  }
2787
3029
 
2788
- const defaultWidgetOptions$s = {
3030
+ const defaultWidgetOptions$r = {
2789
3031
  placeholder: "",
2790
3032
  choices: [{
2791
3033
  content: "",
@@ -2794,12 +3036,12 @@ const defaultWidgetOptions$s = {
2794
3036
  };
2795
3037
  const dropdownWidgetLogic = {
2796
3038
  name: "definition",
2797
- defaultWidgetOptions: defaultWidgetOptions$s,
3039
+ defaultWidgetOptions: defaultWidgetOptions$r,
2798
3040
  defaultAlignment: "inline-block",
2799
3041
  getPublicWidgetOptions: getDropdownPublicWidgetOptions
2800
3042
  };
2801
3043
 
2802
- const defaultWidgetOptions$r = {
3044
+ const defaultWidgetOptions$q = {
2803
3045
  showPrompt: "Explain",
2804
3046
  hidePrompt: "Hide explanation",
2805
3047
  explanation: "explanation goes here\n\nmore explanation",
@@ -2807,31 +3049,46 @@ const defaultWidgetOptions$r = {
2807
3049
  };
2808
3050
  const explanationWidgetLogic = {
2809
3051
  name: "explanation",
2810
- defaultWidgetOptions: defaultWidgetOptions$r,
3052
+ defaultWidgetOptions: defaultWidgetOptions$q,
2811
3053
  defaultAlignment: "inline"
2812
3054
  };
2813
3055
 
2814
- const currentVersion$3 = {
2815
- major: 1,
3056
+ const currentVersion$2 = {
3057
+ major: 2,
2816
3058
  minor: 0
2817
3059
  };
2818
- const widgetOptionsUpgrades$2 = {
2819
- "1": v0options => ({
2820
- times: v0options.times,
2821
- buttonSets: v0options.buttonSets,
2822
- functions: v0options.functions,
2823
- buttonsVisible: v0options.buttonsVisible,
2824
- visibleLabel: v0options.visibleLabel,
2825
- ariaLabel: v0options.ariaLabel,
2826
- answerForms: [{
2827
- considered: "correct",
2828
- form: v0options.form,
2829
- simplify: v0options.simplify,
2830
- value: v0options.value
2831
- }]
2832
- })
3060
+ const widgetOptionsUpgrades$1 = {
3061
+ "2": v1options => {
3062
+ return {
3063
+ times: v1options.times,
3064
+ buttonSets: v1options.buttonSets,
3065
+ functions: v1options.functions,
3066
+ buttonsVisible: v1options.buttonsVisible,
3067
+ visibleLabel: v1options.visibleLabel,
3068
+ ariaLabel: v1options.ariaLabel,
3069
+ answerForms: v1options.answerForms,
3070
+ extraKeys: v1options.extraKeys || deriveExtraKeys(v1options)
3071
+ };
3072
+ },
3073
+ "1": v0options => {
3074
+ return {
3075
+ times: v0options.times,
3076
+ buttonSets: v0options.buttonSets,
3077
+ functions: v0options.functions,
3078
+ buttonsVisible: v0options.buttonsVisible,
3079
+ visibleLabel: v0options.visibleLabel,
3080
+ ariaLabel: v0options.ariaLabel,
3081
+ extraKeys: v0options.extraKeys,
3082
+ answerForms: [{
3083
+ considered: "correct",
3084
+ form: v0options.form,
3085
+ simplify: v0options.simplify,
3086
+ value: v0options.value
3087
+ }]
3088
+ };
3089
+ }
2833
3090
  };
2834
- const defaultWidgetOptions$q = {
3091
+ const defaultWidgetOptions$p = {
2835
3092
  answerForms: [],
2836
3093
  times: false,
2837
3094
  buttonSets: ["basic"],
@@ -2854,20 +3111,21 @@ function getExpressionPublicWidgetOptions(options) {
2854
3111
  times: options.times,
2855
3112
  visibleLabel: options.visibleLabel,
2856
3113
  ariaLabel: options.ariaLabel,
2857
- buttonsVisible: options.buttonsVisible
3114
+ buttonsVisible: options.buttonsVisible,
3115
+ extraKeys: options.extraKeys
2858
3116
  };
2859
3117
  }
2860
3118
 
2861
3119
  const expressionWidgetLogic = {
2862
3120
  name: "expression",
2863
- version: currentVersion$3,
2864
- widgetOptionsUpgrades: widgetOptionsUpgrades$2,
2865
- defaultWidgetOptions: defaultWidgetOptions$q,
3121
+ version: currentVersion$2,
3122
+ widgetOptionsUpgrades: widgetOptionsUpgrades$1,
3123
+ defaultWidgetOptions: defaultWidgetOptions$p,
2866
3124
  defaultAlignment: "inline-block",
2867
3125
  getPublicWidgetOptions: getExpressionPublicWidgetOptions
2868
3126
  };
2869
3127
 
2870
- const defaultWidgetOptions$p = {
3128
+ const defaultWidgetOptions$o = {
2871
3129
  title: "",
2872
3130
  content: "",
2873
3131
  widgets: {},
@@ -2876,24 +3134,24 @@ const defaultWidgetOptions$p = {
2876
3134
  };
2877
3135
  const gradedGroupWidgetLogic = {
2878
3136
  name: "graded-group",
2879
- defaultWidgetOptions: defaultWidgetOptions$p
3137
+ defaultWidgetOptions: defaultWidgetOptions$o
2880
3138
  };
2881
3139
 
2882
- const defaultWidgetOptions$o = {
3140
+ const defaultWidgetOptions$n = {
2883
3141
  gradedGroups: []
2884
3142
  };
2885
3143
  const gradedGroupSetWidgetLogic = {
2886
3144
  name: "graded-group-set",
2887
- defaultWidgetOptions: defaultWidgetOptions$o
3145
+ defaultWidgetOptions: defaultWidgetOptions$n
2888
3146
  };
2889
3147
 
2890
- const _excluded$9 = ["correct"];
3148
+ const _excluded$8 = ["correct"];
2891
3149
  function getGrapherPublicWidgetOptions(options) {
2892
- const publicOptions = _objectWithoutPropertiesLoose(options, _excluded$9);
3150
+ const publicOptions = _objectWithoutPropertiesLoose(options, _excluded$8);
2893
3151
  return publicOptions;
2894
3152
  }
2895
3153
 
2896
- const defaultWidgetOptions$n = {
3154
+ const defaultWidgetOptions$m = {
2897
3155
  graph: {
2898
3156
  labels: ["x", "y"],
2899
3157
  range: [[-10, 10], [-10, 10]],
@@ -2915,25 +3173,25 @@ const defaultWidgetOptions$n = {
2915
3173
  };
2916
3174
  const grapherWidgetLogic = {
2917
3175
  name: "grapher",
2918
- defaultWidgetOptions: defaultWidgetOptions$n,
3176
+ defaultWidgetOptions: defaultWidgetOptions$m,
2919
3177
  getPublicWidgetOptions: getGrapherPublicWidgetOptions
2920
3178
  };
2921
3179
 
2922
- const defaultWidgetOptions$m = {
3180
+ const defaultWidgetOptions$l = {
2923
3181
  content: "",
2924
3182
  widgets: {},
2925
3183
  images: {}
2926
3184
  };
2927
3185
  const groupWidgetLogic = {
2928
3186
  name: "group",
2929
- defaultWidgetOptions: defaultWidgetOptions$m
3187
+ defaultWidgetOptions: defaultWidgetOptions$l
2930
3188
  };
2931
3189
 
2932
3190
  function getIFramePublicWidgetOptions(options) {
2933
3191
  return options;
2934
3192
  }
2935
3193
 
2936
- const defaultWidgetOptions$l = {
3194
+ const defaultWidgetOptions$k = {
2937
3195
  url: "",
2938
3196
  settings: [{
2939
3197
  name: "",
@@ -2946,11 +3204,11 @@ const defaultWidgetOptions$l = {
2946
3204
  };
2947
3205
  const iframeWidgetLogic = {
2948
3206
  name: "iframe",
2949
- defaultWidgetOptions: defaultWidgetOptions$l,
3207
+ defaultWidgetOptions: defaultWidgetOptions$k,
2950
3208
  getPublicWidgetOptions: getIFramePublicWidgetOptions
2951
3209
  };
2952
3210
 
2953
- const defaultWidgetOptions$k = {
3211
+ const defaultWidgetOptions$j = {
2954
3212
  title: "",
2955
3213
  range: [[0, 10], [0, 10]],
2956
3214
  box: [400, 400],
@@ -2965,12 +3223,12 @@ const defaultWidgetOptions$k = {
2965
3223
  };
2966
3224
  const imageWidgetLogic = {
2967
3225
  name: "image",
2968
- defaultWidgetOptions: defaultWidgetOptions$k,
3226
+ defaultWidgetOptions: defaultWidgetOptions$j,
2969
3227
  supportedAlignments: ["block", "full-width"],
2970
3228
  defaultAlignment: "block"
2971
3229
  };
2972
3230
 
2973
- const defaultWidgetOptions$j = {
3231
+ const defaultWidgetOptions$i = {
2974
3232
  value: 0,
2975
3233
  simplify: "required",
2976
3234
  size: "normal",
@@ -2981,11 +3239,11 @@ const defaultWidgetOptions$j = {
2981
3239
  };
2982
3240
  const inputNumberWidgetLogic = {
2983
3241
  name: "input-number",
2984
- defaultWidgetOptions: defaultWidgetOptions$j,
3242
+ defaultWidgetOptions: defaultWidgetOptions$i,
2985
3243
  defaultAlignment: "inline-block"
2986
3244
  };
2987
3245
 
2988
- const defaultWidgetOptions$i = {
3246
+ const defaultWidgetOptions$h = {
2989
3247
  graph: {
2990
3248
  box: [400, 400],
2991
3249
  labels: ["x", "y"],
@@ -2998,16 +3256,16 @@ const defaultWidgetOptions$i = {
2998
3256
  };
2999
3257
  const interactionWidgetLogic = {
3000
3258
  name: "interaction",
3001
- defaultWidgetOptions: defaultWidgetOptions$i
3259
+ defaultWidgetOptions: defaultWidgetOptions$h
3002
3260
  };
3003
3261
 
3004
- const _excluded$8 = ["correct"];
3262
+ const _excluded$7 = ["correct"];
3005
3263
  function getInteractiveGraphPublicWidgetOptions(options) {
3006
- const publicOptions = _objectWithoutPropertiesLoose(options, _excluded$8);
3264
+ const publicOptions = _objectWithoutPropertiesLoose(options, _excluded$7);
3007
3265
  return publicOptions;
3008
3266
  }
3009
3267
 
3010
- const defaultWidgetOptions$h = {
3268
+ const defaultWidgetOptions$g = {
3011
3269
  labels: ["x", "y"],
3012
3270
  range: [[-10, 10], [-10, 10]],
3013
3271
  step: [1, 1],
@@ -3027,11 +3285,11 @@ const defaultWidgetOptions$h = {
3027
3285
  };
3028
3286
  const interactiveGraphWidgetLogic = {
3029
3287
  name: "interactive-graph",
3030
- defaultWidgetOptions: defaultWidgetOptions$h,
3288
+ defaultWidgetOptions: defaultWidgetOptions$g,
3031
3289
  getPublicWidgetOptions: getInteractiveGraphPublicWidgetOptions
3032
3290
  };
3033
3291
 
3034
- const _excluded$7 = ["answers"];
3292
+ const _excluded$6 = ["answers"];
3035
3293
  /**
3036
3294
  * For details on the individual options, see the
3037
3295
  * PerseusLabelImageWidgetOptions type
@@ -3043,11 +3301,11 @@ function getLabelImagePublicWidgetOptions(options) {
3043
3301
  });
3044
3302
  }
3045
3303
  function getLabelImageMarkerPublicData(marker) {
3046
- const publicData = _objectWithoutPropertiesLoose(marker, _excluded$7);
3304
+ const publicData = _objectWithoutPropertiesLoose(marker, _excluded$6);
3047
3305
  return publicData;
3048
3306
  }
3049
3307
 
3050
- const defaultWidgetOptions$g = {
3308
+ const defaultWidgetOptions$f = {
3051
3309
  choices: [],
3052
3310
  imageAlt: "",
3053
3311
  imageUrl: "",
@@ -3059,7 +3317,7 @@ const defaultWidgetOptions$g = {
3059
3317
  };
3060
3318
  const labelImageWidgetLogic = {
3061
3319
  name: "label-image",
3062
- defaultWidgetOptions: defaultWidgetOptions$g,
3320
+ defaultWidgetOptions: defaultWidgetOptions$f,
3063
3321
  getPublicWidgetOptions: getLabelImagePublicWidgetOptions
3064
3322
  };
3065
3323
 
@@ -3120,7 +3378,7 @@ function getMatcherPublicWidgetOptions(options) {
3120
3378
  });
3121
3379
  }
3122
3380
 
3123
- const defaultWidgetOptions$f = {
3381
+ const defaultWidgetOptions$e = {
3124
3382
  left: ["$x$", "$y$", "$z$"],
3125
3383
  right: ["$1$", "$2$", "$3$"],
3126
3384
  labels: ["test", "label"],
@@ -3129,17 +3387,17 @@ const defaultWidgetOptions$f = {
3129
3387
  };
3130
3388
  const matcherWidgetLogic = {
3131
3389
  name: "matcher",
3132
- defaultWidgetOptions: defaultWidgetOptions$f,
3390
+ defaultWidgetOptions: defaultWidgetOptions$e,
3133
3391
  getPublicWidgetOptions: getMatcherPublicWidgetOptions
3134
3392
  };
3135
3393
 
3136
- const _excluded$6 = ["answers"];
3394
+ const _excluded$5 = ["answers"];
3137
3395
  function getMatrixPublicWidgetOptions(options) {
3138
- const publicOptions = _objectWithoutPropertiesLoose(options, _excluded$6);
3396
+ const publicOptions = _objectWithoutPropertiesLoose(options, _excluded$5);
3139
3397
  return publicOptions;
3140
3398
  }
3141
3399
 
3142
- const defaultWidgetOptions$e = {
3400
+ const defaultWidgetOptions$d = {
3143
3401
  matrixBoardSize: [3, 3],
3144
3402
  answers: [[]],
3145
3403
  prefix: "",
@@ -3148,23 +3406,23 @@ const defaultWidgetOptions$e = {
3148
3406
  };
3149
3407
  const matrixWidgetLogic = {
3150
3408
  name: "matrix",
3151
- defaultWidgetOptions: defaultWidgetOptions$e,
3409
+ defaultWidgetOptions: defaultWidgetOptions$d,
3152
3410
  getPublicWidgetOptions: getMatrixPublicWidgetOptions
3153
3411
  };
3154
3412
 
3155
- const _excluded$5 = ["imageUrl", "imageTop", "imageLeft"];
3156
- const currentVersion$2 = {
3413
+ const _excluded$4 = ["imageUrl", "imageTop", "imageLeft"];
3414
+ const currentVersion$1 = {
3157
3415
  major: 1,
3158
3416
  minor: 0
3159
3417
  };
3160
- const widgetOptionsUpgrades$1 = {
3418
+ const widgetOptionsUpgrades = {
3161
3419
  "1": v0options => {
3162
3420
  const {
3163
3421
  imageUrl,
3164
3422
  imageTop,
3165
3423
  imageLeft
3166
3424
  } = v0options,
3167
- rest = _objectWithoutPropertiesLoose(v0options, _excluded$5);
3425
+ rest = _objectWithoutPropertiesLoose(v0options, _excluded$4);
3168
3426
  return _extends({}, rest, {
3169
3427
  image: {
3170
3428
  url: imageUrl,
@@ -3174,7 +3432,7 @@ const widgetOptionsUpgrades$1 = {
3174
3432
  });
3175
3433
  }
3176
3434
  };
3177
- const defaultWidgetOptions$d = {
3435
+ const defaultWidgetOptions$c = {
3178
3436
  box: [480, 480],
3179
3437
  image: {},
3180
3438
  showProtractor: true,
@@ -3187,18 +3445,18 @@ const defaultWidgetOptions$d = {
3187
3445
 
3188
3446
  const measurerWidgetLogic = {
3189
3447
  name: "measurer",
3190
- version: currentVersion$2,
3191
- widgetOptionsUpgrades: widgetOptionsUpgrades$1,
3192
- defaultWidgetOptions: defaultWidgetOptions$d
3448
+ version: currentVersion$1,
3449
+ widgetOptionsUpgrades: widgetOptionsUpgrades,
3450
+ defaultWidgetOptions: defaultWidgetOptions$c
3193
3451
  };
3194
3452
 
3195
- const _excluded$4 = ["correctX", "correctRel"];
3453
+ const _excluded$3 = ["correctX", "correctRel"];
3196
3454
  function getNumberLinePublicWidgetOptions(options) {
3197
- const publicOptions = _objectWithoutPropertiesLoose(options, _excluded$4);
3455
+ const publicOptions = _objectWithoutPropertiesLoose(options, _excluded$3);
3198
3456
  return publicOptions;
3199
3457
  }
3200
3458
 
3201
- const defaultWidgetOptions$c = {
3459
+ const defaultWidgetOptions$b = {
3202
3460
  range: [0, 10],
3203
3461
  labelRange: [null, null],
3204
3462
  labelStyle: "decimal",
@@ -3214,11 +3472,11 @@ const defaultWidgetOptions$c = {
3214
3472
  };
3215
3473
  const numberLineWidgetLogic = {
3216
3474
  name: "number-line",
3217
- defaultWidgetOptions: defaultWidgetOptions$c,
3475
+ defaultWidgetOptions: defaultWidgetOptions$b,
3218
3476
  getPublicWidgetOptions: getNumberLinePublicWidgetOptions
3219
3477
  };
3220
3478
 
3221
- const _excluded$3 = ["answers"];
3479
+ const _excluded$2 = ["answers"];
3222
3480
  /**
3223
3481
  * For details on the individual options, see the
3224
3482
  * PerseusNumericInputWidgetOptions type
@@ -3249,13 +3507,13 @@ function getNumericInputPublicWidgetOptions(options) {
3249
3507
  const {
3250
3508
  answers
3251
3509
  } = options,
3252
- publicWidgetOptions = _objectWithoutPropertiesLoose(options, _excluded$3);
3510
+ publicWidgetOptions = _objectWithoutPropertiesLoose(options, _excluded$2);
3253
3511
  return _extends({}, publicWidgetOptions, {
3254
3512
  answers: answers.map(getNumericInputAnswerPublicData)
3255
3513
  });
3256
3514
  }
3257
3515
 
3258
- const defaultWidgetOptions$b = {
3516
+ const defaultWidgetOptions$a = {
3259
3517
  answers: [{
3260
3518
  value: null,
3261
3519
  status: "correct",
@@ -3272,7 +3530,7 @@ const defaultWidgetOptions$b = {
3272
3530
  };
3273
3531
  const numericInputWidgetLogic = {
3274
3532
  name: "numeric-input",
3275
- defaultWidgetOptions: defaultWidgetOptions$b,
3533
+ defaultWidgetOptions: defaultWidgetOptions$a,
3276
3534
  defaultAlignment: "inline-block",
3277
3535
  getPublicWidgetOptions: getNumericInputPublicWidgetOptions
3278
3536
  };
@@ -3294,7 +3552,7 @@ function getOrdererPublicWidgetOptions(options) {
3294
3552
  };
3295
3553
  }
3296
3554
 
3297
- const defaultWidgetOptions$a = {
3555
+ const defaultWidgetOptions$9 = {
3298
3556
  correctOptions: [{
3299
3557
  content: "$x$"
3300
3558
  }],
@@ -3306,11 +3564,11 @@ const defaultWidgetOptions$a = {
3306
3564
  };
3307
3565
  const ordererWidgetLogic = {
3308
3566
  name: "orderer",
3309
- defaultWidgetOptions: defaultWidgetOptions$a,
3567
+ defaultWidgetOptions: defaultWidgetOptions$9,
3310
3568
  getPublicWidgetOptions: getOrdererPublicWidgetOptions
3311
3569
  };
3312
3570
 
3313
- const defaultWidgetOptions$9 = {
3571
+ const defaultWidgetOptions$8 = {
3314
3572
  passageTitle: "",
3315
3573
  passageText: "",
3316
3574
  footnotes: "",
@@ -3318,14 +3576,14 @@ const defaultWidgetOptions$9 = {
3318
3576
  };
3319
3577
  const passageWidgetLogic = {
3320
3578
  name: "passage",
3321
- defaultWidgetOptions: defaultWidgetOptions$9
3579
+ defaultWidgetOptions: defaultWidgetOptions$8
3322
3580
  };
3323
3581
 
3324
- const currentVersion$1 = {
3582
+ const currentVersion = {
3325
3583
  major: 0,
3326
3584
  minor: 1
3327
3585
  };
3328
- const defaultWidgetOptions$8 = {
3586
+ const defaultWidgetOptions$7 = {
3329
3587
  passageNumber: 1,
3330
3588
  referenceNumber: 1,
3331
3589
  summaryText: ""
@@ -3333,30 +3591,30 @@ const defaultWidgetOptions$8 = {
3333
3591
 
3334
3592
  const passageRefWidgetLogic = {
3335
3593
  name: "passageRef",
3336
- version: currentVersion$1,
3337
- defaultWidgetOptions: defaultWidgetOptions$8,
3594
+ version: currentVersion,
3595
+ defaultWidgetOptions: defaultWidgetOptions$7,
3338
3596
  defaultAlignment: "inline"
3339
3597
  };
3340
3598
 
3341
- const defaultWidgetOptions$7 = {
3599
+ const defaultWidgetOptions$6 = {
3342
3600
  content: ""
3343
3601
  };
3344
3602
  const passageRefTargetWidgetLogic = {
3345
3603
  name: "passageRefTarget",
3346
- defaultWidgetOptions: defaultWidgetOptions$7,
3604
+ defaultWidgetOptions: defaultWidgetOptions$6,
3347
3605
  defaultAlignment: "inline"
3348
3606
  };
3349
3607
 
3350
- const defaultWidgetOptions$6 = {
3608
+ const defaultWidgetOptions$5 = {
3351
3609
  url: "",
3352
3610
  description: ""
3353
3611
  };
3354
3612
  const phetSimulationWidgetLogic = {
3355
3613
  name: "phet-simulation",
3356
- defaultWidgetOptions: defaultWidgetOptions$6
3614
+ defaultWidgetOptions: defaultWidgetOptions$5
3357
3615
  };
3358
3616
 
3359
- const _excluded$2 = ["correct"];
3617
+ const _excluded$1 = ["correct"];
3360
3618
  /**
3361
3619
  * For details on the individual options, see the
3362
3620
  * PerseusPlotterWidgetOptions type
@@ -3367,11 +3625,11 @@ const _excluded$2 = ["correct"];
3367
3625
  * the public options that should be exposed to the client.
3368
3626
  */
3369
3627
  function getPlotterPublicWidgetOptions(options) {
3370
- const publicOptions = _objectWithoutPropertiesLoose(options, _excluded$2);
3628
+ const publicOptions = _objectWithoutPropertiesLoose(options, _excluded$1);
3371
3629
  return publicOptions;
3372
3630
  }
3373
3631
 
3374
- const defaultWidgetOptions$5 = {
3632
+ const defaultWidgetOptions$4 = {
3375
3633
  scaleY: 1,
3376
3634
  maxY: 10,
3377
3635
  snapsPerLine: 2,
@@ -3388,46 +3646,17 @@ const defaultWidgetOptions$5 = {
3388
3646
  };
3389
3647
  const plotterWidgetLogic = {
3390
3648
  name: "plotter",
3391
- defaultWidgetOptions: defaultWidgetOptions$5,
3649
+ defaultWidgetOptions: defaultWidgetOptions$4,
3392
3650
  getPublicWidgetOptions: getPlotterPublicWidgetOptions
3393
3651
  };
3394
3652
 
3395
- const defaultWidgetOptions$4 = {
3653
+ const defaultWidgetOptions$3 = {
3396
3654
  programID: "",
3397
3655
  height: 400
3398
3656
  };
3399
3657
  const pythonProgramWidgetLogic = {
3400
3658
  name: "python-program",
3401
- defaultWidgetOptions: defaultWidgetOptions$4
3402
- };
3403
-
3404
- const _excluded$1 = ["noneOfTheAbove"];
3405
- const currentVersion = {
3406
- major: 1,
3407
- minor: 0
3408
- };
3409
- const widgetOptionsUpgrades = {
3410
- "1": v0props => {
3411
- const {
3412
- noneOfTheAbove
3413
- } = v0props,
3414
- rest = _objectWithoutPropertiesLoose(v0props, _excluded$1);
3415
- if (noneOfTheAbove) {
3416
- throw new Error("radio widget v0 no longer supports auto noneOfTheAbove");
3417
- }
3418
- return _extends({}, rest, {
3419
- hasNoneOfTheAbove: false
3420
- });
3421
- }
3422
- };
3423
- const defaultWidgetOptions$3 = {
3424
- choices: [{}, {}, {}, {}],
3425
- displayCount: null,
3426
- randomize: false,
3427
- hasNoneOfTheAbove: false,
3428
- multipleSelect: false,
3429
- countChoices: false,
3430
- deselectEnabled: false
3659
+ defaultWidgetOptions: defaultWidgetOptions$3
3431
3660
  };
3432
3661
 
3433
3662
  /**
@@ -3456,21 +3685,40 @@ function getRadioChoicePublicData(choice) {
3456
3685
  };
3457
3686
  }
3458
3687
 
3688
+ /**
3689
+ * Shared functionality to determine if numCorrect is used, because:
3690
+ *
3691
+ * 1. numCorrect is conditionally used for rendering pre-scoring
3692
+ * 2. numCorrect also exposes information about answers
3693
+ *
3694
+ * So only include/use numCorrect when we know it's useful.
3695
+ */
3696
+ function usesNumCorrect(multipleSelect, countChoices, numCorrect) {
3697
+ return multipleSelect && countChoices && numCorrect;
3698
+ }
3699
+
3459
3700
  /**
3460
3701
  * Given a PerseusRadioWidgetOptions object, return a new object with only
3461
3702
  * the public options that should be exposed to the client.
3462
3703
  */
3463
3704
  function getRadioPublicWidgetOptions(options) {
3705
+ const {
3706
+ numCorrect,
3707
+ choices,
3708
+ multipleSelect,
3709
+ countChoices
3710
+ } = options;
3464
3711
  return _extends({}, options, {
3465
- choices: options.choices.map(getRadioChoicePublicData)
3712
+ numCorrect: usesNumCorrect(multipleSelect, countChoices, numCorrect) ? numCorrect : undefined,
3713
+ choices: choices.map(getRadioChoicePublicData)
3466
3714
  });
3467
3715
  }
3468
3716
 
3469
3717
  const radioWidgetLogic = {
3470
3718
  name: "radio",
3471
- version: currentVersion,
3472
- widgetOptionsUpgrades: widgetOptionsUpgrades,
3473
- defaultWidgetOptions: defaultWidgetOptions$3,
3719
+ version: currentVersion$3,
3720
+ widgetOptionsUpgrades: widgetOptionsUpgrades$2,
3721
+ defaultWidgetOptions: defaultWidgetOptions$v,
3474
3722
  getPublicWidgetOptions: getRadioPublicWidgetOptions
3475
3723
  };
3476
3724
 
@@ -3846,5 +4094,5 @@ function shuffle(array, randomSeed, ensurePermuted = false) {
3846
4094
  }
3847
4095
  const random = seededRNG(new Date().getTime() & 0xffffffff);
3848
4096
 
3849
- export { coreWidgetRegistry as CoreWidgetRegistry, Errors, grapherUtil as GrapherUtil, ItemExtras, PerseusError, PerseusExpressionAnswerFormConsidered, addWidget, approximateDeepEqual, approximateEqual, categorizerWidgetLogic as categorizerLogic, csProgramWidgetLogic as csProgramLogic, deepClone, definitionWidgetLogic as definitionLogic, dropdownWidgetLogic as dropdownLogic, explanationWidgetLogic as explanationLogic, expressionWidgetLogic as expressionLogic, getCSProgramPublicWidgetOptions, getCategorizerPublicWidgetOptions, getDecimalSeparator, getDropdownPublicWidgetOptions, getExpressionPublicWidgetOptions, getGrapherPublicWidgetOptions, getIFramePublicWidgetOptions, getInteractiveGraphPublicWidgetOptions, getLabelImagePublicWidgetOptions, getMatcherPublicWidgetOptions, getMatrixPublicWidgetOptions, getMatrixSize, getNumberLinePublicWidgetOptions, getNumericInputPublicWidgetOptions, getOrdererPublicWidgetOptions, getPlotterPublicWidgetOptions, getRadioPublicWidgetOptions, getSorterPublicWidgetOptions, getTablePublicWidgetOptions, getUpgradedWidgetOptions, getWidgetIdsFromContent, getWidgetIdsFromContentByType, gradedGroupWidgetLogic as gradedGroupLogic, gradedGroupSetWidgetLogic as gradedGroupSetLogic, grapherWidgetLogic as grapherLogic, groupWidgetLogic as groupLogic, iframeWidgetLogic as iframeLogic, imageWidgetLogic as imageLogic, inputNumberWidgetLogic as inputNumberLogic, interactionWidgetLogic as interactionLogic, interactiveGraphWidgetLogic as interactiveGraphLogic, isFailure, isSuccess, labelImageWidgetLogic as labelImageLogic, libVersion, lockedFigureColorNames, lockedFigureColors, lockedFigureFillStyles, mapObject, matcherWidgetLogic as matcherLogic, matrixWidgetLogic as matrixLogic, measurerWidgetLogic as measurerLogic, numberLineWidgetLogic as numberLineLogic, numericInputWidgetLogic as numericInputLogic, ordererWidgetLogic as ordererLogic, parseAndMigratePerseusArticle, parseAndMigratePerseusItem, parsePerseusItem, passageWidgetLogic as passageLogic, passageRefWidgetLogic as passageRefLogic, passageRefTargetWidgetLogic as passageRefTargetLogic, phetSimulationWidgetLogic as phetSimulationLogic, plotterWidgetLogic as plotterLogic, plotterPlotTypes, pluck, pythonProgramWidgetLogic as pythonProgramLogic, radioWidgetLogic as radioLogic, random, seededRNG, shuffle, shuffleMatcher, sorterWidgetLogic as sorterLogic, splitPerseusItem, tableWidgetLogic as tableLogic, upgradeWidgetInfoToLatestVersion, videoWidgetLogic as videoLogic };
4097
+ export { coreWidgetRegistry as CoreWidgetRegistry, Errors, grapherUtil as GrapherUtil, ItemExtras, PerseusError, PerseusExpressionAnswerFormConsidered, addWidget, approximateDeepEqual, approximateEqual, categorizerWidgetLogic as categorizerLogic, csProgramWidgetLogic as csProgramLogic, deepClone, definitionWidgetLogic as definitionLogic, deriveExtraKeys, deriveNumCorrect, dropdownWidgetLogic as dropdownLogic, explanationWidgetLogic as explanationLogic, expressionWidgetLogic as expressionLogic, getCSProgramPublicWidgetOptions, getCategorizerPublicWidgetOptions, getDecimalSeparator, getDropdownPublicWidgetOptions, getExpressionPublicWidgetOptions, getGrapherPublicWidgetOptions, getIFramePublicWidgetOptions, getInteractiveGraphPublicWidgetOptions, getLabelImagePublicWidgetOptions, getMatcherPublicWidgetOptions, getMatrixPublicWidgetOptions, getMatrixSize, getNumberLinePublicWidgetOptions, getNumericInputPublicWidgetOptions, getOrdererPublicWidgetOptions, getPlotterPublicWidgetOptions, getRadioPublicWidgetOptions, getSorterPublicWidgetOptions, getTablePublicWidgetOptions, getUpgradedWidgetOptions, getWidgetIdsFromContent, getWidgetIdsFromContentByType, gradedGroupWidgetLogic as gradedGroupLogic, gradedGroupSetWidgetLogic as gradedGroupSetLogic, grapherWidgetLogic as grapherLogic, groupWidgetLogic as groupLogic, iframeWidgetLogic as iframeLogic, imageWidgetLogic as imageLogic, inputNumberWidgetLogic as inputNumberLogic, interactionWidgetLogic as interactionLogic, interactiveGraphWidgetLogic as interactiveGraphLogic, isFailure, isSuccess, labelImageWidgetLogic as labelImageLogic, libVersion, lockedFigureColorNames, lockedFigureColors, lockedFigureFillStyles, mapObject, matcherWidgetLogic as matcherLogic, matrixWidgetLogic as matrixLogic, measurerWidgetLogic as measurerLogic, numberLineWidgetLogic as numberLineLogic, numericInputWidgetLogic as numericInputLogic, ordererWidgetLogic as ordererLogic, parseAndMigratePerseusArticle, parseAndMigratePerseusItem, parsePerseusItem, passageWidgetLogic as passageLogic, passageRefWidgetLogic as passageRefLogic, passageRefTargetWidgetLogic as passageRefTargetLogic, phetSimulationWidgetLogic as phetSimulationLogic, plotterWidgetLogic as plotterLogic, plotterPlotTypes, pluck, pythonProgramWidgetLogic as pythonProgramLogic, radioWidgetLogic as radioLogic, random, seededRNG, shuffle, shuffleMatcher, sorterWidgetLogic as sorterLogic, splitPerseusItem, tableWidgetLogic as tableLogic, upgradeWidgetInfoToLatestVersion, usesNumCorrect, videoWidgetLogic as videoLogic };
3850
4098
  //# sourceMappingURL=index.js.map