@khanacademy/perseus 54.0.0 → 54.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -2197,55 +2197,6 @@ const rWidgetRule = /^\[\[\u2603 (([a-z-]+) ([0-9]+))\]\]/;
2197
2197
  const rTypeFromWidgetId = /^([a-z-]+) ([0-9]+)$/;
2198
2198
  const rWidgetParts = new RegExp(rWidgetRule.source + "$");
2199
2199
  const snowman = "\u2603";
2200
- const seededRNG$1 = function (seed) {
2201
- let randomSeed = seed;
2202
- return function () {
2203
- // Robert Jenkins' 32 bit integer hash function.
2204
- let seed = randomSeed;
2205
- seed = seed + 0x7ed55d16 + (seed << 12) & 0xffffffff;
2206
- seed = (seed ^ 0xc761c23c ^ seed >>> 19) & 0xffffffff;
2207
- seed = seed + 0x165667b1 + (seed << 5) & 0xffffffff;
2208
- seed = (seed + 0xd3a2646c ^ seed << 9) & 0xffffffff;
2209
- seed = seed + 0xfd7046c5 + (seed << 3) & 0xffffffff;
2210
- seed = (seed ^ 0xb55a4f09 ^ seed >>> 16) & 0xffffffff;
2211
- return (randomSeed = seed & 0xfffffff) / 0x10000000;
2212
- };
2213
- };
2214
-
2215
- // Shuffle an array using a given random seed or function.
2216
- // If `ensurePermuted` is true, the input and ouput are guaranteed to be
2217
- // distinct permutations.
2218
- function shuffle$3(array, randomSeed) {
2219
- let ensurePermuted = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
2220
- // Always return a copy of the input array
2221
- const shuffled = ___default["default"].clone(array);
2222
-
2223
- // Handle edge cases (input array is empty or uniform)
2224
- if (!shuffled.length || ___default["default"].all(shuffled, function (value) {
2225
- return ___default["default"].isEqual(value, shuffled[0]);
2226
- })) {
2227
- return shuffled;
2228
- }
2229
- let random;
2230
- if (typeof randomSeed === "function") {
2231
- random = randomSeed;
2232
- } else {
2233
- random = seededRNG$1(randomSeed);
2234
- }
2235
- do {
2236
- // Fischer-Yates shuffle
2237
- for (let top = shuffled.length; top > 0; top--) {
2238
- const newEnd = Math.floor(random() * top);
2239
- const temp = shuffled[newEnd];
2240
-
2241
- // @ts-expect-error - TS2542 - Index signature in type 'readonly T[]' only permits reading.
2242
- shuffled[newEnd] = shuffled[top - 1];
2243
- // @ts-expect-error - TS2542 - Index signature in type 'readonly T[]' only permits reading.
2244
- shuffled[top - 1] = temp;
2245
- }
2246
- } while (ensurePermuted && ___default["default"].isEqual(array, shuffled));
2247
- return shuffled;
2248
- }
2249
2200
 
2250
2201
  /**
2251
2202
  * TODO(somewhatabstract, FEI-3463):
@@ -2676,7 +2627,6 @@ const textarea = {
2676
2627
  * to translate it but don't need the extra dollar signs.
2677
2628
  */
2678
2629
  const unescapeMathMode$1 = label => label.startsWith("$") && label.endsWith("$") ? label.slice(1, -1) : label;
2679
- const random$1 = seededRNG$1(new Date().getTime() & 0xffffffff);
2680
2630
  const Util = {
2681
2631
  inputPathsEqual,
2682
2632
  nestedMap: nestedMap$2,
@@ -2684,8 +2634,6 @@ const Util = {
2684
2634
  rTypeFromWidgetId,
2685
2635
  rWidgetParts,
2686
2636
  snowman,
2687
- seededRNG: seededRNG$1,
2688
- shuffle: shuffle$3,
2689
2637
  split,
2690
2638
  firstNumericalParse: firstNumericalParse$1,
2691
2639
  stringArrayOfSize: stringArrayOfSize$1,
@@ -2713,8 +2661,7 @@ const Util = {
2713
2661
  getSvgUrl: getSvgUrl,
2714
2662
  getDataUrl: getDataUrl,
2715
2663
  textarea,
2716
- unescapeMathMode: unescapeMathMode$1,
2717
- random: random$1
2664
+ unescapeMathMode: unescapeMathMode$1
2718
2665
  };
2719
2666
 
2720
2667
  // TODO(LP-11481): Change the primary API we use for logging in Perseus to use
@@ -24743,22 +24690,17 @@ class Radio$1 extends React__namespace.Component {
24743
24690
  }
24744
24691
  }
24745
24692
 
24746
- const {
24747
- shuffle: shuffle$2,
24748
- random
24749
- } = Util;
24750
-
24751
24693
  // Transforms the choices for display.
24752
24694
  const _choiceTransform = (widgetOptions, strings, problemNum) => {
24753
24695
  const _maybeRandomize = function (array) {
24754
- const randomSeed = problemNum === undefined ? random : problemNum;
24696
+ const randomSeed = problemNum === undefined ? perseusCore.random : problemNum;
24755
24697
  // NOTE: `problemNum` will only be set when the radio widget is
24756
24698
  // rendered at the root of an exercise question. It will be `undefined`
24757
24699
  // if it's rendered embedded in another widget, such as `graded-group`,
24758
24700
  // or if rendered within an article. This results in a predictable
24759
24701
  // shuffle order. To avoid this we use a random seed when `problemNum`
24760
24702
  // is `undefined`.
24761
- return widgetOptions.randomize ? shuffle$2(array, randomSeed ?? 0) : array;
24703
+ return widgetOptions.randomize ? perseusCore.shuffle(array, randomSeed ?? 0) : array;
24762
24704
  };
24763
24705
  const _addNoneOfAbove = function (choices) {
24764
24706
  let noneOfTheAbove = null;
@@ -24999,8 +24941,7 @@ class Categorizer extends React__namespace.Component {
24999
24941
  const isMobile = this.props.apiOptions.isMobile;
25000
24942
  let indexedItems = this.props.items.map((item, n) => [item, n]);
25001
24943
  if (this.props.randomizeItems) {
25002
- // @ts-expect-error - TS4104 - The type 'readonly (string | number)[][]' is 'readonly' and cannot be assigned to the mutable type '(string | number)[][]'. | TS2345 - Argument of type 'number | null | undefined' is not assignable to parameter of type 'number | RNG'.
25003
- indexedItems = Util.shuffle(indexedItems, this.props.problemNum);
24944
+ indexedItems = perseusCore.shuffle(indexedItems, this.props.problemNum);
25004
24945
  }
25005
24946
  const table = /*#__PURE__*/React__namespace.createElement("table", {
25006
24947
  className: "categorizer-table " + aphrodite.css(styles$n.mobileTable)
@@ -25026,9 +24967,7 @@ class Categorizer extends React__namespace.Component {
25026
24967
  const uniqueId = self.state.uniqueId + "_" + itemNum;
25027
24968
  return /*#__PURE__*/React__namespace.createElement("tr", {
25028
24969
  key: itemNum
25029
- }, /*#__PURE__*/React__namespace.createElement("td", null, /*#__PURE__*/React__namespace.createElement(Renderer
25030
- // @ts-expect-error - TS2322 - Type 'string | number' is not assignable to type 'string | undefined'.
25031
- , {
24970
+ }, /*#__PURE__*/React__namespace.createElement("td", null, /*#__PURE__*/React__namespace.createElement(Renderer, {
25032
24971
  content: item,
25033
24972
  linterContext: this.props.linterContext,
25034
24973
  strings: this.context.strings
@@ -37551,10 +37490,6 @@ const getPromptJSON$9 = (renderProps, userInput) => {
37551
37490
  };
37552
37491
  };
37553
37492
 
37554
- const {
37555
- shuffle: shuffle$1,
37556
- seededRNG
37557
- } = Util;
37558
37493
  const HACKY_CSS_CLASSNAME = "perseus-widget-matcher";
37559
37494
  class Matcher extends React__namespace.Component {
37560
37495
  static contextType = PerseusI18nContext;
@@ -37656,16 +37591,16 @@ class Matcher extends React__namespace.Component {
37656
37591
  }, "1")));
37657
37592
  }
37658
37593
 
37659
- // Use the same random() function to shuffle both columns sequentially
37660
- const rng = seededRNG(this.props.problemNum);
37661
- let left;
37662
- if (!this.props.orderMatters) {
37663
- // If the order doesn't matter, don't shuffle the left column
37664
- left = this.props.left;
37665
- } else {
37666
- left = shuffle$1(this.props.left, rng, /* ensurePermuted */true);
37667
- }
37668
- const right = shuffle$1(this.props.right, rng, /* ensurePermuted */true);
37594
+ /* TODO(LEMS-2841):
37595
+ Once the getMatcherPublicWidgetOptions function gets connected to the
37596
+ widget, we'll need to update this to the line below to only shuffle
37597
+ on the server.
37598
+ const {left, right} = this.props;
37599
+ */
37600
+ const {
37601
+ left,
37602
+ right
37603
+ } = perseusCore.shuffleMatcher(this.props);
37669
37604
  const showLabels = ___default["default"].any(this.props.labels);
37670
37605
  const constraints = {
37671
37606
  height: ___default["default"].max([this.state.leftHeight, this.state.rightHeight])
@@ -41431,9 +41366,6 @@ const getPromptJSON$1 = userInput => {
41431
41366
  };
41432
41367
  };
41433
41368
 
41434
- const {
41435
- shuffle
41436
- } = Util;
41437
41369
  class Sorter extends React__namespace.Component {
41438
41370
  _isMounted = false;
41439
41371
  static defaultProps = {
@@ -41490,7 +41422,11 @@ class Sorter extends React__namespace.Component {
41490
41422
  this.refs.sortable.moveOptionToIndex(option, index);
41491
41423
  };
41492
41424
  render() {
41493
- const options = shuffle(this.props.correct, this.props.problemNum, /* ensurePermuted */true);
41425
+ // TODO(LEMS-2841): Remove client-side shuffle once receiving public
41426
+ // options. The correct field will already be shuffled.
41427
+ // Probably easiest to replace "options" with "this.props.correct" when
41428
+ // setting up Sortable below. Or use the assignment to rename for clarity.
41429
+ const options = perseusCore.shuffle(this.props.correct, this.props.problemNum, /* ensurePermuted */true);
41494
41430
  const {
41495
41431
  apiOptions
41496
41432
  } = this.props;
@@ -41911,7 +41847,7 @@ const init = function () {
41911
41847
 
41912
41848
  // This file is processed by a Rollup plugin (replace) to inject the production
41913
41849
  const libName = "@khanacademy/perseus";
41914
- const libVersion = "54.0.0";
41850
+ const libVersion = "54.1.0";
41915
41851
  perseusCore.addLibraryVersionToPerseusDebug(libName, libVersion);
41916
41852
 
41917
41853
  const apiVersion = {