@khanacademy/perseus-core 5.4.1 → 5.4.2
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 +63 -105
- package/dist/es/index.js.map +1 -1
- package/dist/index.js +65 -106
- package/dist/index.js.map +1 -1
- package/dist/parse-perseus-json/perseus-parsers/perseus-answer-area.d.ts +1 -1
- package/dist/widgets/categorizer/categorizer-util.d.ts +1 -1
- package/dist/widgets/dropdown/dropdown-util.d.ts +1 -1
- package/dist/widgets/expression/expression-util.d.ts +1 -1
- package/dist/widgets/interactive-graph/interactive-graph-util.d.ts +1 -1
- package/dist/widgets/label-image/label-image-util.d.ts +1 -1
- package/dist/widgets/matcher/matcher-util.d.ts +1 -1
- package/dist/widgets/matrix/matrix-util.d.ts +1 -1
- package/dist/widgets/numeric-input/numeric-input-util.d.ts +1 -1
- package/dist/widgets/orderer/orderer-util.d.ts +1 -1
- package/dist/widgets/plotter/plotter-util.d.ts +1 -1
- package/dist/widgets/radio/radio-util.d.ts +1 -1
- package/dist/widgets/sorter/sorter-util.d.ts +1 -1
- package/dist/widgets/table/table-util.d.ts +1 -1
- package/package.json +5 -3
- package/dist/shared-utils/add-library-version-to-perseus-debug.d.ts +0 -9
package/dist/index.js
CHANGED
|
@@ -4,7 +4,7 @@ Object.defineProperty(exports, '__esModule', { value: true });
|
|
|
4
4
|
|
|
5
5
|
var _ = require('underscore');
|
|
6
6
|
var KAS = require('@khanacademy/kas');
|
|
7
|
-
var
|
|
7
|
+
var perseusUtils = require('@khanacademy/perseus-utils');
|
|
8
8
|
|
|
9
9
|
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
10
10
|
|
|
@@ -2780,10 +2780,10 @@ const parsePerseusItem$1 = object({
|
|
|
2780
2780
|
question: parsePerseusRenderer,
|
|
2781
2781
|
hints: defaulted(array(parseHint), () => []),
|
|
2782
2782
|
answerArea: parsePerseusAnswerArea,
|
|
2783
|
-
itemDataVersion: optional(object({
|
|
2783
|
+
itemDataVersion: optional(nullable(object({
|
|
2784
2784
|
major: number,
|
|
2785
2785
|
minor: number
|
|
2786
|
-
})),
|
|
2786
|
+
}))),
|
|
2787
2787
|
// Deprecated field
|
|
2788
2788
|
answer: any
|
|
2789
2789
|
});
|
|
@@ -2860,51 +2860,10 @@ function throwErrorIfCheatingDetected() {
|
|
|
2860
2860
|
}
|
|
2861
2861
|
}
|
|
2862
2862
|
|
|
2863
|
-
/**
|
|
2864
|
-
* Adds the given perseus library version information to the __perseus_debug__
|
|
2865
|
-
* object and ensures that the object is attached to `globalThis` (`window` in
|
|
2866
|
-
* browser environments).
|
|
2867
|
-
*
|
|
2868
|
-
* This allows each library to provide runtime version information to assist in
|
|
2869
|
-
* debugging in production environments.
|
|
2870
|
-
*/
|
|
2871
|
-
const addLibraryVersionToPerseusDebug = (libraryName, libraryVersion) => {
|
|
2872
|
-
// If the library version is the default value, then we don't want to
|
|
2873
|
-
// prefix it with a "v" to indicate that it is a version number.
|
|
2874
|
-
let prefix = "v";
|
|
2875
|
-
if (libraryVersion === "__lib_version__") {
|
|
2876
|
-
prefix = "";
|
|
2877
|
-
}
|
|
2878
|
-
const formattedVersion = `${prefix}${libraryVersion}`;
|
|
2879
|
-
if (typeof globalThis !== "undefined") {
|
|
2880
|
-
globalThis.__perseus_debug__ = globalThis.__perseus_debug__ ?? {};
|
|
2881
|
-
const existingVersionEntry = globalThis.__perseus_debug__[libraryName];
|
|
2882
|
-
if (existingVersionEntry) {
|
|
2883
|
-
// If we already have an entry and it doesn't match the registered
|
|
2884
|
-
// version, we morph the entry into an array and log a warning.
|
|
2885
|
-
if (existingVersionEntry !== formattedVersion) {
|
|
2886
|
-
// Existing entry might be an array already (oops, at least 2
|
|
2887
|
-
// versions of the library already loaded!).
|
|
2888
|
-
const allVersions = Array.isArray(existingVersionEntry) ? existingVersionEntry : [existingVersionEntry];
|
|
2889
|
-
allVersions.push(formattedVersion);
|
|
2890
|
-
globalThis.__perseus_debug__[libraryName] = allVersions;
|
|
2891
|
-
|
|
2892
|
-
// eslint-disable-next-line no-console
|
|
2893
|
-
console.warn(`Multiple versions of ${libraryName} loaded on this page: ${allVersions.sort().join(", ")}`);
|
|
2894
|
-
}
|
|
2895
|
-
} else {
|
|
2896
|
-
globalThis.__perseus_debug__[libraryName] = formattedVersion;
|
|
2897
|
-
}
|
|
2898
|
-
} else {
|
|
2899
|
-
// eslint-disable-next-line no-console
|
|
2900
|
-
console.warn(`globalThis not found found (${formattedVersion})`);
|
|
2901
|
-
}
|
|
2902
|
-
};
|
|
2903
|
-
|
|
2904
2863
|
// This file is processed by a Rollup plugin (replace) to inject the production
|
|
2905
2864
|
const libName = "@khanacademy/perseus-core";
|
|
2906
|
-
const libVersion = "5.4.
|
|
2907
|
-
addLibraryVersionToPerseusDebug(libName, libVersion);
|
|
2865
|
+
const libVersion = "5.4.2";
|
|
2866
|
+
perseusUtils.addLibraryVersionToPerseusDebug(libName, libVersion);
|
|
2908
2867
|
|
|
2909
2868
|
/**
|
|
2910
2869
|
* @typedef {Object} Errors utility for referencing the Perseus error taxonomy.
|
|
@@ -3387,20 +3346,74 @@ const labelImageWidgetLogic = {
|
|
|
3387
3346
|
getPublicWidgetOptions: getLabelImagePublicWidgetOptions
|
|
3388
3347
|
};
|
|
3389
3348
|
|
|
3349
|
+
/* Note(tamara): Brought over from the perseus package packages/perseus/src/util.ts file.
|
|
3350
|
+
May be useful to bring other perseus package utilities here. Contains utility functions
|
|
3351
|
+
and types used across multiple widgets for randomization and shuffling. */
|
|
3352
|
+
const seededRNG = function (seed) {
|
|
3353
|
+
let randomSeed = seed;
|
|
3354
|
+
return function () {
|
|
3355
|
+
// Robert Jenkins' 32 bit integer hash function.
|
|
3356
|
+
let seed = randomSeed;
|
|
3357
|
+
seed = seed + 0x7ed55d16 + (seed << 12) & 0xffffffff;
|
|
3358
|
+
seed = (seed ^ 0xc761c23c ^ seed >>> 19) & 0xffffffff;
|
|
3359
|
+
seed = seed + 0x165667b1 + (seed << 5) & 0xffffffff;
|
|
3360
|
+
seed = (seed + 0xd3a2646c ^ seed << 9) & 0xffffffff;
|
|
3361
|
+
seed = seed + 0xfd7046c5 + (seed << 3) & 0xffffffff;
|
|
3362
|
+
seed = (seed ^ 0xb55a4f09 ^ seed >>> 16) & 0xffffffff;
|
|
3363
|
+
return (randomSeed = seed & 0xfffffff) / 0x10000000;
|
|
3364
|
+
};
|
|
3365
|
+
};
|
|
3366
|
+
|
|
3367
|
+
// Shuffle an array using a given random seed or function.
|
|
3368
|
+
// If `ensurePermuted` is true, the input and output are guaranteed to be
|
|
3369
|
+
// distinct permutations.
|
|
3370
|
+
function shuffle(array, randomSeed) {
|
|
3371
|
+
let ensurePermuted = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
|
|
3372
|
+
// Always return a copy of the input array
|
|
3373
|
+
const shuffled = ___default["default"].clone(array);
|
|
3374
|
+
|
|
3375
|
+
// Handle edge cases (input array is empty or uniform)
|
|
3376
|
+
if (!shuffled.length || ___default["default"].all(shuffled, function (value) {
|
|
3377
|
+
return ___default["default"].isEqual(value, shuffled[0]);
|
|
3378
|
+
})) {
|
|
3379
|
+
return shuffled;
|
|
3380
|
+
}
|
|
3381
|
+
let random;
|
|
3382
|
+
if (typeof randomSeed === "function") {
|
|
3383
|
+
random = randomSeed;
|
|
3384
|
+
} else {
|
|
3385
|
+
random = seededRNG(randomSeed);
|
|
3386
|
+
}
|
|
3387
|
+
do {
|
|
3388
|
+
// Fischer-Yates shuffle
|
|
3389
|
+
for (let top = shuffled.length; top > 0; top--) {
|
|
3390
|
+
const newEnd = Math.floor(random() * top);
|
|
3391
|
+
const temp = shuffled[newEnd];
|
|
3392
|
+
|
|
3393
|
+
// @ts-expect-error - TS2542 - Index signature in type 'readonly T[]' only permits reading.
|
|
3394
|
+
shuffled[newEnd] = shuffled[top - 1];
|
|
3395
|
+
// @ts-expect-error - TS2542 - Index signature in type 'readonly T[]' only permits reading.
|
|
3396
|
+
shuffled[top - 1] = temp;
|
|
3397
|
+
}
|
|
3398
|
+
} while (ensurePermuted && ___default["default"].isEqual(array, shuffled));
|
|
3399
|
+
return shuffled;
|
|
3400
|
+
}
|
|
3401
|
+
const random = seededRNG(new Date().getTime() & 0xffffffff);
|
|
3402
|
+
|
|
3390
3403
|
// TODO(LEMS-2841): Should be able to remove once getPublicWidgetOptions is hooked up
|
|
3391
3404
|
|
|
3392
3405
|
// TODO(LEMS-2841): Should be able to remove once getPublicWidgetOptions is hooked up
|
|
3393
3406
|
const shuffleMatcher = props => {
|
|
3394
3407
|
// Use the same random() function to shuffle both columns sequentially
|
|
3395
|
-
const rng =
|
|
3408
|
+
const rng = seededRNG(props.problemNum);
|
|
3396
3409
|
let left;
|
|
3397
3410
|
if (!props.orderMatters) {
|
|
3398
3411
|
// If the order doesn't matter, don't shuffle the left column
|
|
3399
3412
|
left = props.left;
|
|
3400
3413
|
} else {
|
|
3401
|
-
left =
|
|
3414
|
+
left = shuffle(props.left, rng, /* ensurePermuted */true);
|
|
3402
3415
|
}
|
|
3403
|
-
const right =
|
|
3416
|
+
const right = shuffle(props.right, rng, /* ensurePermuted */true);
|
|
3404
3417
|
return {
|
|
3405
3418
|
left,
|
|
3406
3419
|
right
|
|
@@ -3415,9 +3428,9 @@ function shuffleMatcherWithRandom(data) {
|
|
|
3415
3428
|
// If the order doesn't matter, don't shuffle the left column
|
|
3416
3429
|
left = data.left;
|
|
3417
3430
|
} else {
|
|
3418
|
-
left =
|
|
3431
|
+
left = shuffle(data.left, Math.random, /* ensurePermuted */true);
|
|
3419
3432
|
}
|
|
3420
|
-
const right =
|
|
3433
|
+
const right = shuffle(data.right, Math.random, /* ensurePermuted */true);
|
|
3421
3434
|
return {
|
|
3422
3435
|
left,
|
|
3423
3436
|
right
|
|
@@ -3807,7 +3820,7 @@ const radioWidgetLogic = {
|
|
|
3807
3820
|
* the public options that should be exposed to the client.
|
|
3808
3821
|
*/
|
|
3809
3822
|
function getSorterPublicWidgetOptions(options) {
|
|
3810
|
-
const shuffledCorrect =
|
|
3823
|
+
const shuffledCorrect = shuffle(options.correct, Math.random, /* ensurePermuted */true);
|
|
3811
3824
|
return {
|
|
3812
3825
|
...options,
|
|
3813
3826
|
// Note(Tamara): This does not provide correct answer information any longer.
|
|
@@ -4129,60 +4142,6 @@ function splitPerseusItem(originalItem) {
|
|
|
4129
4142
|
};
|
|
4130
4143
|
}
|
|
4131
4144
|
|
|
4132
|
-
/* Note(tamara): Brought over from the perseus package packages/perseus/src/util.ts file.
|
|
4133
|
-
May be useful to bring other perseus package utilities here. Contains utility functions
|
|
4134
|
-
and types used across multiple widgets for randomization and shuffling. */
|
|
4135
|
-
const seededRNG = function (seed) {
|
|
4136
|
-
let randomSeed = seed;
|
|
4137
|
-
return function () {
|
|
4138
|
-
// Robert Jenkins' 32 bit integer hash function.
|
|
4139
|
-
let seed = randomSeed;
|
|
4140
|
-
seed = seed + 0x7ed55d16 + (seed << 12) & 0xffffffff;
|
|
4141
|
-
seed = (seed ^ 0xc761c23c ^ seed >>> 19) & 0xffffffff;
|
|
4142
|
-
seed = seed + 0x165667b1 + (seed << 5) & 0xffffffff;
|
|
4143
|
-
seed = (seed + 0xd3a2646c ^ seed << 9) & 0xffffffff;
|
|
4144
|
-
seed = seed + 0xfd7046c5 + (seed << 3) & 0xffffffff;
|
|
4145
|
-
seed = (seed ^ 0xb55a4f09 ^ seed >>> 16) & 0xffffffff;
|
|
4146
|
-
return (randomSeed = seed & 0xfffffff) / 0x10000000;
|
|
4147
|
-
};
|
|
4148
|
-
};
|
|
4149
|
-
|
|
4150
|
-
// Shuffle an array using a given random seed or function.
|
|
4151
|
-
// If `ensurePermuted` is true, the input and output are guaranteed to be
|
|
4152
|
-
// distinct permutations.
|
|
4153
|
-
function shuffle(array, randomSeed) {
|
|
4154
|
-
let ensurePermuted = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
|
|
4155
|
-
// Always return a copy of the input array
|
|
4156
|
-
const shuffled = ___default["default"].clone(array);
|
|
4157
|
-
|
|
4158
|
-
// Handle edge cases (input array is empty or uniform)
|
|
4159
|
-
if (!shuffled.length || ___default["default"].all(shuffled, function (value) {
|
|
4160
|
-
return ___default["default"].isEqual(value, shuffled[0]);
|
|
4161
|
-
})) {
|
|
4162
|
-
return shuffled;
|
|
4163
|
-
}
|
|
4164
|
-
let random;
|
|
4165
|
-
if (typeof randomSeed === "function") {
|
|
4166
|
-
random = randomSeed;
|
|
4167
|
-
} else {
|
|
4168
|
-
random = seededRNG(randomSeed);
|
|
4169
|
-
}
|
|
4170
|
-
do {
|
|
4171
|
-
// Fischer-Yates shuffle
|
|
4172
|
-
for (let top = shuffled.length; top > 0; top--) {
|
|
4173
|
-
const newEnd = Math.floor(random() * top);
|
|
4174
|
-
const temp = shuffled[newEnd];
|
|
4175
|
-
|
|
4176
|
-
// @ts-expect-error - TS2542 - Index signature in type 'readonly T[]' only permits reading.
|
|
4177
|
-
shuffled[newEnd] = shuffled[top - 1];
|
|
4178
|
-
// @ts-expect-error - TS2542 - Index signature in type 'readonly T[]' only permits reading.
|
|
4179
|
-
shuffled[top - 1] = temp;
|
|
4180
|
-
}
|
|
4181
|
-
} while (ensurePermuted && ___default["default"].isEqual(array, shuffled));
|
|
4182
|
-
return shuffled;
|
|
4183
|
-
}
|
|
4184
|
-
const random = seededRNG(new Date().getTime() & 0xffffffff);
|
|
4185
|
-
|
|
4186
4145
|
exports.CoreWidgetRegistry = coreWidgetRegistry;
|
|
4187
4146
|
exports.Errors = Errors;
|
|
4188
4147
|
exports.GrapherUtil = grapherUtil;
|