@khanacademy/perseus-core 3.7.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/LICENSE +18 -0
- package/dist/data-schema.d.ts +18 -4
- package/dist/es/index.js +483 -2243
- package/dist/es/index.js.map +1 -1
- package/dist/index.d.ts +8 -3
- package/dist/index.js +519 -2230
- package/dist/index.js.map +1 -1
- package/dist/keypad.d.ts +12 -0
- package/dist/parse-perseus-json/perseus-parsers/interactive-graph-widget.d.ts +1 -0
- package/dist/types.d.ts +0 -3
- package/dist/widgets/dropdown/dropdown-util.d.ts +1 -1
- package/dist/widgets/expression/derive-extra-keys.d.ts +8 -0
- package/dist/widgets/expression/expression-upgrade.d.ts +1 -0
- package/dist/widgets/expression/expression-util.d.ts +2 -1
- package/dist/widgets/interactive-graph/interactive-graph-util.d.ts +1 -2
- package/dist/widgets/numeric-input/numeric-input-util.d.ts +3 -2
- package/dist/widgets/radio/radio-upgrade.d.ts +2 -0
- package/dist/widgets/radio/radio-util.d.ts +10 -0
- package/package.json +35 -32
- /package/dist/{utils → shared-utils}/add-library-version-to-perseus-debug.d.ts +0 -0
package/dist/index.js
CHANGED
|
@@ -2,2081 +2,41 @@
|
|
|
2
2
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
|
+
var _ = require('underscore');
|
|
6
|
+
var KAS = require('@khanacademy/kas');
|
|
5
7
|
var perseusCore = require('@khanacademy/perseus-core');
|
|
6
8
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
const formattedVersion = `${prefix}${libraryVersion}`;
|
|
23
|
-
if (typeof globalThis !== "undefined") {
|
|
24
|
-
globalThis.__perseus_debug__ = globalThis.__perseus_debug__ ?? {};
|
|
25
|
-
const existingVersionEntry = globalThis.__perseus_debug__[libraryName];
|
|
26
|
-
if (existingVersionEntry) {
|
|
27
|
-
// If we already have an entry and it doesn't match the registered
|
|
28
|
-
// version, we morph the entry into an array and log a warning.
|
|
29
|
-
if (existingVersionEntry !== formattedVersion) {
|
|
30
|
-
// Existing entry might be an array already (oops, at least 2
|
|
31
|
-
// versions of the library already loaded!).
|
|
32
|
-
const allVersions = Array.isArray(existingVersionEntry) ? existingVersionEntry : [existingVersionEntry];
|
|
33
|
-
allVersions.push(formattedVersion);
|
|
34
|
-
globalThis.__perseus_debug__[libraryName] = allVersions;
|
|
35
|
-
|
|
36
|
-
// eslint-disable-next-line no-console
|
|
37
|
-
console.warn(`Multiple versions of ${libraryName} loaded on this page: ${allVersions.sort().join(", ")}`);
|
|
38
|
-
}
|
|
39
|
-
} else {
|
|
40
|
-
globalThis.__perseus_debug__[libraryName] = formattedVersion;
|
|
41
|
-
}
|
|
42
|
-
} else {
|
|
43
|
-
// eslint-disable-next-line no-console
|
|
44
|
-
console.warn(`globalThis not found found (${formattedVersion})`);
|
|
45
|
-
}
|
|
46
|
-
};
|
|
47
|
-
|
|
48
|
-
// Current version.
|
|
49
|
-
var VERSION = '1.13.3';
|
|
50
|
-
|
|
51
|
-
// Establish the root object, `window` (`self`) in the browser, `global`
|
|
52
|
-
// on the server, or `this` in some virtual machines. We use `self`
|
|
53
|
-
// instead of `window` for `WebWorker` support.
|
|
54
|
-
var root = (typeof self == 'object' && self.self === self && self) ||
|
|
55
|
-
(typeof global == 'object' && global.global === global && global) ||
|
|
56
|
-
Function('return this')() ||
|
|
57
|
-
{};
|
|
58
|
-
|
|
59
|
-
// Save bytes in the minified (but not gzipped) version:
|
|
60
|
-
var ArrayProto = Array.prototype, ObjProto = Object.prototype;
|
|
61
|
-
var SymbolProto = typeof Symbol !== 'undefined' ? Symbol.prototype : null;
|
|
62
|
-
|
|
63
|
-
// Create quick reference variables for speed access to core prototypes.
|
|
64
|
-
var push = ArrayProto.push,
|
|
65
|
-
slice = ArrayProto.slice,
|
|
66
|
-
toString = ObjProto.toString,
|
|
67
|
-
hasOwnProperty = ObjProto.hasOwnProperty;
|
|
68
|
-
|
|
69
|
-
// Modern feature detection.
|
|
70
|
-
var supportsArrayBuffer = typeof ArrayBuffer !== 'undefined',
|
|
71
|
-
supportsDataView = typeof DataView !== 'undefined';
|
|
72
|
-
|
|
73
|
-
// All **ECMAScript 5+** native function implementations that we hope to use
|
|
74
|
-
// are declared here.
|
|
75
|
-
var nativeIsArray = Array.isArray,
|
|
76
|
-
nativeKeys = Object.keys,
|
|
77
|
-
nativeCreate = Object.create,
|
|
78
|
-
nativeIsView = supportsArrayBuffer && ArrayBuffer.isView;
|
|
79
|
-
|
|
80
|
-
// Create references to these builtin functions because we override them.
|
|
81
|
-
var _isNaN = isNaN,
|
|
82
|
-
_isFinite = isFinite;
|
|
83
|
-
|
|
84
|
-
// Keys in IE < 9 that won't be iterated by `for key in ...` and thus missed.
|
|
85
|
-
var hasEnumBug = !{toString: null}.propertyIsEnumerable('toString');
|
|
86
|
-
var nonEnumerableProps = ['valueOf', 'isPrototypeOf', 'toString',
|
|
87
|
-
'propertyIsEnumerable', 'hasOwnProperty', 'toLocaleString'];
|
|
88
|
-
|
|
89
|
-
// The largest integer that can be represented exactly.
|
|
90
|
-
var MAX_ARRAY_INDEX = Math.pow(2, 53) - 1;
|
|
91
|
-
|
|
92
|
-
// Some functions take a variable number of arguments, or a few expected
|
|
93
|
-
// arguments at the beginning and then a variable number of values to operate
|
|
94
|
-
// on. This helper accumulates all remaining arguments past the function’s
|
|
95
|
-
// argument length (or an explicit `startIndex`), into an array that becomes
|
|
96
|
-
// the last argument. Similar to ES6’s "rest parameter".
|
|
97
|
-
function restArguments(func, startIndex) {
|
|
98
|
-
startIndex = startIndex == null ? func.length - 1 : +startIndex;
|
|
99
|
-
return function() {
|
|
100
|
-
var length = Math.max(arguments.length - startIndex, 0),
|
|
101
|
-
rest = Array(length),
|
|
102
|
-
index = 0;
|
|
103
|
-
for (; index < length; index++) {
|
|
104
|
-
rest[index] = arguments[index + startIndex];
|
|
105
|
-
}
|
|
106
|
-
switch (startIndex) {
|
|
107
|
-
case 0: return func.call(this, rest);
|
|
108
|
-
case 1: return func.call(this, arguments[0], rest);
|
|
109
|
-
case 2: return func.call(this, arguments[0], arguments[1], rest);
|
|
110
|
-
}
|
|
111
|
-
var args = Array(startIndex + 1);
|
|
112
|
-
for (index = 0; index < startIndex; index++) {
|
|
113
|
-
args[index] = arguments[index];
|
|
114
|
-
}
|
|
115
|
-
args[startIndex] = rest;
|
|
116
|
-
return func.apply(this, args);
|
|
117
|
-
};
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
// Is a given variable an object?
|
|
121
|
-
function isObject$1(obj) {
|
|
122
|
-
var type = typeof obj;
|
|
123
|
-
return type === 'function' || (type === 'object' && !!obj);
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
// Is a given value equal to null?
|
|
127
|
-
function isNull(obj) {
|
|
128
|
-
return obj === null;
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
// Is a given variable undefined?
|
|
132
|
-
function isUndefined(obj) {
|
|
133
|
-
return obj === void 0;
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
// Is a given value a boolean?
|
|
137
|
-
function isBoolean(obj) {
|
|
138
|
-
return obj === true || obj === false || toString.call(obj) === '[object Boolean]';
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
// Is a given value a DOM element?
|
|
142
|
-
function isElement(obj) {
|
|
143
|
-
return !!(obj && obj.nodeType === 1);
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
// Internal function for creating a `toString`-based type tester.
|
|
147
|
-
function tagTester(name) {
|
|
148
|
-
var tag = '[object ' + name + ']';
|
|
149
|
-
return function(obj) {
|
|
150
|
-
return toString.call(obj) === tag;
|
|
151
|
-
};
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
var isString = tagTester('String');
|
|
155
|
-
|
|
156
|
-
var isNumber = tagTester('Number');
|
|
157
|
-
|
|
158
|
-
var isDate = tagTester('Date');
|
|
159
|
-
|
|
160
|
-
var isRegExp = tagTester('RegExp');
|
|
161
|
-
|
|
162
|
-
var isError = tagTester('Error');
|
|
163
|
-
|
|
164
|
-
var isSymbol = tagTester('Symbol');
|
|
165
|
-
|
|
166
|
-
var isArrayBuffer = tagTester('ArrayBuffer');
|
|
167
|
-
|
|
168
|
-
var isFunction = tagTester('Function');
|
|
169
|
-
|
|
170
|
-
// Optimize `isFunction` if appropriate. Work around some `typeof` bugs in old
|
|
171
|
-
// v8, IE 11 (#1621), Safari 8 (#1929), and PhantomJS (#2236).
|
|
172
|
-
var nodelist = root.document && root.document.childNodes;
|
|
173
|
-
if (typeof /./ != 'function' && typeof Int8Array != 'object' && typeof nodelist != 'function') {
|
|
174
|
-
isFunction = function(obj) {
|
|
175
|
-
return typeof obj == 'function' || false;
|
|
176
|
-
};
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
var isFunction$1 = isFunction;
|
|
180
|
-
|
|
181
|
-
var hasObjectTag = tagTester('Object');
|
|
182
|
-
|
|
183
|
-
// In IE 10 - Edge 13, `DataView` has string tag `'[object Object]'`.
|
|
184
|
-
// In IE 11, the most common among them, this problem also applies to
|
|
185
|
-
// `Map`, `WeakMap` and `Set`.
|
|
186
|
-
var hasStringTagBug = (
|
|
187
|
-
supportsDataView && hasObjectTag(new DataView(new ArrayBuffer(8)))
|
|
188
|
-
),
|
|
189
|
-
isIE11 = (typeof Map !== 'undefined' && hasObjectTag(new Map));
|
|
190
|
-
|
|
191
|
-
var isDataView = tagTester('DataView');
|
|
192
|
-
|
|
193
|
-
// In IE 10 - Edge 13, we need a different heuristic
|
|
194
|
-
// to determine whether an object is a `DataView`.
|
|
195
|
-
function ie10IsDataView(obj) {
|
|
196
|
-
return obj != null && isFunction$1(obj.getInt8) && isArrayBuffer(obj.buffer);
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
var isDataView$1 = (hasStringTagBug ? ie10IsDataView : isDataView);
|
|
200
|
-
|
|
201
|
-
// Is a given value an array?
|
|
202
|
-
// Delegates to ECMA5's native `Array.isArray`.
|
|
203
|
-
var isArray = nativeIsArray || tagTester('Array');
|
|
204
|
-
|
|
205
|
-
// Internal function to check whether `key` is an own property name of `obj`.
|
|
206
|
-
function has$1(obj, key) {
|
|
207
|
-
return obj != null && hasOwnProperty.call(obj, key);
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
var isArguments = tagTester('Arguments');
|
|
211
|
-
|
|
212
|
-
// Define a fallback version of the method in browsers (ahem, IE < 9), where
|
|
213
|
-
// there isn't any inspectable "Arguments" type.
|
|
214
|
-
(function() {
|
|
215
|
-
if (!isArguments(arguments)) {
|
|
216
|
-
isArguments = function(obj) {
|
|
217
|
-
return has$1(obj, 'callee');
|
|
218
|
-
};
|
|
219
|
-
}
|
|
220
|
-
}());
|
|
221
|
-
|
|
222
|
-
var isArguments$1 = isArguments;
|
|
223
|
-
|
|
224
|
-
// Is a given object a finite number?
|
|
225
|
-
function isFinite$1(obj) {
|
|
226
|
-
return !isSymbol(obj) && _isFinite(obj) && !isNaN(parseFloat(obj));
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
// Is the given value `NaN`?
|
|
230
|
-
function isNaN$1(obj) {
|
|
231
|
-
return isNumber(obj) && _isNaN(obj);
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
// Predicate-generating function. Often useful outside of Underscore.
|
|
235
|
-
function constant$1(value) {
|
|
236
|
-
return function() {
|
|
237
|
-
return value;
|
|
238
|
-
};
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
// Common internal logic for `isArrayLike` and `isBufferLike`.
|
|
242
|
-
function createSizePropertyCheck(getSizeProperty) {
|
|
243
|
-
return function(collection) {
|
|
244
|
-
var sizeProperty = getSizeProperty(collection);
|
|
245
|
-
return typeof sizeProperty == 'number' && sizeProperty >= 0 && sizeProperty <= MAX_ARRAY_INDEX;
|
|
246
|
-
}
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
// Internal helper to generate a function to obtain property `key` from `obj`.
|
|
250
|
-
function shallowProperty(key) {
|
|
251
|
-
return function(obj) {
|
|
252
|
-
return obj == null ? void 0 : obj[key];
|
|
253
|
-
};
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
// Internal helper to obtain the `byteLength` property of an object.
|
|
257
|
-
var getByteLength = shallowProperty('byteLength');
|
|
258
|
-
|
|
259
|
-
// Internal helper to determine whether we should spend extensive checks against
|
|
260
|
-
// `ArrayBuffer` et al.
|
|
261
|
-
var isBufferLike = createSizePropertyCheck(getByteLength);
|
|
262
|
-
|
|
263
|
-
// Is a given value a typed array?
|
|
264
|
-
var typedArrayPattern = /\[object ((I|Ui)nt(8|16|32)|Float(32|64)|Uint8Clamped|Big(I|Ui)nt64)Array\]/;
|
|
265
|
-
function isTypedArray(obj) {
|
|
266
|
-
// `ArrayBuffer.isView` is the most future-proof, so use it when available.
|
|
267
|
-
// Otherwise, fall back on the above regular expression.
|
|
268
|
-
return nativeIsView ? (nativeIsView(obj) && !isDataView$1(obj)) :
|
|
269
|
-
isBufferLike(obj) && typedArrayPattern.test(toString.call(obj));
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
var isTypedArray$1 = supportsArrayBuffer ? isTypedArray : constant$1(false);
|
|
273
|
-
|
|
274
|
-
// Internal helper to obtain the `length` property of an object.
|
|
275
|
-
var getLength = shallowProperty('length');
|
|
276
|
-
|
|
277
|
-
// Internal helper to create a simple lookup structure.
|
|
278
|
-
// `collectNonEnumProps` used to depend on `_.contains`, but this led to
|
|
279
|
-
// circular imports. `emulatedSet` is a one-off solution that only works for
|
|
280
|
-
// arrays of strings.
|
|
281
|
-
function emulatedSet(keys) {
|
|
282
|
-
var hash = {};
|
|
283
|
-
for (var l = keys.length, i = 0; i < l; ++i) hash[keys[i]] = true;
|
|
284
|
-
return {
|
|
285
|
-
contains: function(key) { return hash[key] === true; },
|
|
286
|
-
push: function(key) {
|
|
287
|
-
hash[key] = true;
|
|
288
|
-
return keys.push(key);
|
|
289
|
-
}
|
|
290
|
-
};
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
// Internal helper. Checks `keys` for the presence of keys in IE < 9 that won't
|
|
294
|
-
// be iterated by `for key in ...` and thus missed. Extends `keys` in place if
|
|
295
|
-
// needed.
|
|
296
|
-
function collectNonEnumProps(obj, keys) {
|
|
297
|
-
keys = emulatedSet(keys);
|
|
298
|
-
var nonEnumIdx = nonEnumerableProps.length;
|
|
299
|
-
var constructor = obj.constructor;
|
|
300
|
-
var proto = (isFunction$1(constructor) && constructor.prototype) || ObjProto;
|
|
301
|
-
|
|
302
|
-
// Constructor is a special case.
|
|
303
|
-
var prop = 'constructor';
|
|
304
|
-
if (has$1(obj, prop) && !keys.contains(prop)) keys.push(prop);
|
|
305
|
-
|
|
306
|
-
while (nonEnumIdx--) {
|
|
307
|
-
prop = nonEnumerableProps[nonEnumIdx];
|
|
308
|
-
if (prop in obj && obj[prop] !== proto[prop] && !keys.contains(prop)) {
|
|
309
|
-
keys.push(prop);
|
|
310
|
-
}
|
|
311
|
-
}
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
// Retrieve the names of an object's own properties.
|
|
315
|
-
// Delegates to **ECMAScript 5**'s native `Object.keys`.
|
|
316
|
-
function keys(obj) {
|
|
317
|
-
if (!isObject$1(obj)) return [];
|
|
318
|
-
if (nativeKeys) return nativeKeys(obj);
|
|
319
|
-
var keys = [];
|
|
320
|
-
for (var key in obj) if (has$1(obj, key)) keys.push(key);
|
|
321
|
-
// Ahem, IE < 9.
|
|
322
|
-
if (hasEnumBug) collectNonEnumProps(obj, keys);
|
|
323
|
-
return keys;
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
// Is a given array, string, or object empty?
|
|
327
|
-
// An "empty" object has no enumerable own-properties.
|
|
328
|
-
function isEmpty(obj) {
|
|
329
|
-
if (obj == null) return true;
|
|
330
|
-
// Skip the more expensive `toString`-based type checks if `obj` has no
|
|
331
|
-
// `.length`.
|
|
332
|
-
var length = getLength(obj);
|
|
333
|
-
if (typeof length == 'number' && (
|
|
334
|
-
isArray(obj) || isString(obj) || isArguments$1(obj)
|
|
335
|
-
)) return length === 0;
|
|
336
|
-
return getLength(keys(obj)) === 0;
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
// Returns whether an object has a given set of `key:value` pairs.
|
|
340
|
-
function isMatch(object, attrs) {
|
|
341
|
-
var _keys = keys(attrs), length = _keys.length;
|
|
342
|
-
if (object == null) return !length;
|
|
343
|
-
var obj = Object(object);
|
|
344
|
-
for (var i = 0; i < length; i++) {
|
|
345
|
-
var key = _keys[i];
|
|
346
|
-
if (attrs[key] !== obj[key] || !(key in obj)) return false;
|
|
347
|
-
}
|
|
348
|
-
return true;
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
// If Underscore is called as a function, it returns a wrapped object that can
|
|
352
|
-
// be used OO-style. This wrapper holds altered versions of all functions added
|
|
353
|
-
// through `_.mixin`. Wrapped objects may be chained.
|
|
354
|
-
function _$1(obj) {
|
|
355
|
-
if (obj instanceof _$1) return obj;
|
|
356
|
-
if (!(this instanceof _$1)) return new _$1(obj);
|
|
357
|
-
this._wrapped = obj;
|
|
358
|
-
}
|
|
359
|
-
|
|
360
|
-
_$1.VERSION = VERSION;
|
|
361
|
-
|
|
362
|
-
// Extracts the result from a wrapped and chained object.
|
|
363
|
-
_$1.prototype.value = function() {
|
|
364
|
-
return this._wrapped;
|
|
365
|
-
};
|
|
366
|
-
|
|
367
|
-
// Provide unwrapping proxies for some methods used in engine operations
|
|
368
|
-
// such as arithmetic and JSON stringification.
|
|
369
|
-
_$1.prototype.valueOf = _$1.prototype.toJSON = _$1.prototype.value;
|
|
370
|
-
|
|
371
|
-
_$1.prototype.toString = function() {
|
|
372
|
-
return String(this._wrapped);
|
|
373
|
-
};
|
|
374
|
-
|
|
375
|
-
// Internal function to wrap or shallow-copy an ArrayBuffer,
|
|
376
|
-
// typed array or DataView to a new view, reusing the buffer.
|
|
377
|
-
function toBufferView(bufferSource) {
|
|
378
|
-
return new Uint8Array(
|
|
379
|
-
bufferSource.buffer || bufferSource,
|
|
380
|
-
bufferSource.byteOffset || 0,
|
|
381
|
-
getByteLength(bufferSource)
|
|
382
|
-
);
|
|
383
|
-
}
|
|
384
|
-
|
|
385
|
-
// We use this string twice, so give it a name for minification.
|
|
386
|
-
var tagDataView = '[object DataView]';
|
|
387
|
-
|
|
388
|
-
// Internal recursive comparison function for `_.isEqual`.
|
|
389
|
-
function eq(a, b, aStack, bStack) {
|
|
390
|
-
// Identical objects are equal. `0 === -0`, but they aren't identical.
|
|
391
|
-
// See the [Harmony `egal` proposal](https://wiki.ecmascript.org/doku.php?id=harmony:egal).
|
|
392
|
-
if (a === b) return a !== 0 || 1 / a === 1 / b;
|
|
393
|
-
// `null` or `undefined` only equal to itself (strict comparison).
|
|
394
|
-
if (a == null || b == null) return false;
|
|
395
|
-
// `NaN`s are equivalent, but non-reflexive.
|
|
396
|
-
if (a !== a) return b !== b;
|
|
397
|
-
// Exhaust primitive checks
|
|
398
|
-
var type = typeof a;
|
|
399
|
-
if (type !== 'function' && type !== 'object' && typeof b != 'object') return false;
|
|
400
|
-
return deepEq(a, b, aStack, bStack);
|
|
401
|
-
}
|
|
402
|
-
|
|
403
|
-
// Internal recursive comparison function for `_.isEqual`.
|
|
404
|
-
function deepEq(a, b, aStack, bStack) {
|
|
405
|
-
// Unwrap any wrapped objects.
|
|
406
|
-
if (a instanceof _$1) a = a._wrapped;
|
|
407
|
-
if (b instanceof _$1) b = b._wrapped;
|
|
408
|
-
// Compare `[[Class]]` names.
|
|
409
|
-
var className = toString.call(a);
|
|
410
|
-
if (className !== toString.call(b)) return false;
|
|
411
|
-
// Work around a bug in IE 10 - Edge 13.
|
|
412
|
-
if (hasStringTagBug && className == '[object Object]' && isDataView$1(a)) {
|
|
413
|
-
if (!isDataView$1(b)) return false;
|
|
414
|
-
className = tagDataView;
|
|
415
|
-
}
|
|
416
|
-
switch (className) {
|
|
417
|
-
// These types are compared by value.
|
|
418
|
-
case '[object RegExp]':
|
|
419
|
-
// RegExps are coerced to strings for comparison (Note: '' + /a/i === '/a/i')
|
|
420
|
-
case '[object String]':
|
|
421
|
-
// Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is
|
|
422
|
-
// equivalent to `new String("5")`.
|
|
423
|
-
return '' + a === '' + b;
|
|
424
|
-
case '[object Number]':
|
|
425
|
-
// `NaN`s are equivalent, but non-reflexive.
|
|
426
|
-
// Object(NaN) is equivalent to NaN.
|
|
427
|
-
if (+a !== +a) return +b !== +b;
|
|
428
|
-
// An `egal` comparison is performed for other numeric values.
|
|
429
|
-
return +a === 0 ? 1 / +a === 1 / b : +a === +b;
|
|
430
|
-
case '[object Date]':
|
|
431
|
-
case '[object Boolean]':
|
|
432
|
-
// Coerce dates and booleans to numeric primitive values. Dates are compared by their
|
|
433
|
-
// millisecond representations. Note that invalid dates with millisecond representations
|
|
434
|
-
// of `NaN` are not equivalent.
|
|
435
|
-
return +a === +b;
|
|
436
|
-
case '[object Symbol]':
|
|
437
|
-
return SymbolProto.valueOf.call(a) === SymbolProto.valueOf.call(b);
|
|
438
|
-
case '[object ArrayBuffer]':
|
|
439
|
-
case tagDataView:
|
|
440
|
-
// Coerce to typed array so we can fall through.
|
|
441
|
-
return deepEq(toBufferView(a), toBufferView(b), aStack, bStack);
|
|
442
|
-
}
|
|
443
|
-
|
|
444
|
-
var areArrays = className === '[object Array]';
|
|
445
|
-
if (!areArrays && isTypedArray$1(a)) {
|
|
446
|
-
var byteLength = getByteLength(a);
|
|
447
|
-
if (byteLength !== getByteLength(b)) return false;
|
|
448
|
-
if (a.buffer === b.buffer && a.byteOffset === b.byteOffset) return true;
|
|
449
|
-
areArrays = true;
|
|
450
|
-
}
|
|
451
|
-
if (!areArrays) {
|
|
452
|
-
if (typeof a != 'object' || typeof b != 'object') return false;
|
|
453
|
-
|
|
454
|
-
// Objects with different constructors are not equivalent, but `Object`s or `Array`s
|
|
455
|
-
// from different frames are.
|
|
456
|
-
var aCtor = a.constructor, bCtor = b.constructor;
|
|
457
|
-
if (aCtor !== bCtor && !(isFunction$1(aCtor) && aCtor instanceof aCtor &&
|
|
458
|
-
isFunction$1(bCtor) && bCtor instanceof bCtor)
|
|
459
|
-
&& ('constructor' in a && 'constructor' in b)) {
|
|
460
|
-
return false;
|
|
461
|
-
}
|
|
462
|
-
}
|
|
463
|
-
// Assume equality for cyclic structures. The algorithm for detecting cyclic
|
|
464
|
-
// structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.
|
|
465
|
-
|
|
466
|
-
// Initializing stack of traversed objects.
|
|
467
|
-
// It's done here since we only need them for objects and arrays comparison.
|
|
468
|
-
aStack = aStack || [];
|
|
469
|
-
bStack = bStack || [];
|
|
470
|
-
var length = aStack.length;
|
|
471
|
-
while (length--) {
|
|
472
|
-
// Linear search. Performance is inversely proportional to the number of
|
|
473
|
-
// unique nested structures.
|
|
474
|
-
if (aStack[length] === a) return bStack[length] === b;
|
|
475
|
-
}
|
|
476
|
-
|
|
477
|
-
// Add the first object to the stack of traversed objects.
|
|
478
|
-
aStack.push(a);
|
|
479
|
-
bStack.push(b);
|
|
480
|
-
|
|
481
|
-
// Recursively compare objects and arrays.
|
|
482
|
-
if (areArrays) {
|
|
483
|
-
// Compare array lengths to determine if a deep comparison is necessary.
|
|
484
|
-
length = a.length;
|
|
485
|
-
if (length !== b.length) return false;
|
|
486
|
-
// Deep compare the contents, ignoring non-numeric properties.
|
|
487
|
-
while (length--) {
|
|
488
|
-
if (!eq(a[length], b[length], aStack, bStack)) return false;
|
|
489
|
-
}
|
|
490
|
-
} else {
|
|
491
|
-
// Deep compare objects.
|
|
492
|
-
var _keys = keys(a), key;
|
|
493
|
-
length = _keys.length;
|
|
494
|
-
// Ensure that both objects contain the same number of properties before comparing deep equality.
|
|
495
|
-
if (keys(b).length !== length) return false;
|
|
496
|
-
while (length--) {
|
|
497
|
-
// Deep compare each member
|
|
498
|
-
key = _keys[length];
|
|
499
|
-
if (!(has$1(b, key) && eq(a[key], b[key], aStack, bStack))) return false;
|
|
500
|
-
}
|
|
501
|
-
}
|
|
502
|
-
// Remove the first object from the stack of traversed objects.
|
|
503
|
-
aStack.pop();
|
|
504
|
-
bStack.pop();
|
|
505
|
-
return true;
|
|
506
|
-
}
|
|
507
|
-
|
|
508
|
-
// Perform a deep comparison to check if two objects are equal.
|
|
509
|
-
function isEqual(a, b) {
|
|
510
|
-
return eq(a, b);
|
|
511
|
-
}
|
|
512
|
-
|
|
513
|
-
// Retrieve all the enumerable property names of an object.
|
|
514
|
-
function allKeys(obj) {
|
|
515
|
-
if (!isObject$1(obj)) return [];
|
|
516
|
-
var keys = [];
|
|
517
|
-
for (var key in obj) keys.push(key);
|
|
518
|
-
// Ahem, IE < 9.
|
|
519
|
-
if (hasEnumBug) collectNonEnumProps(obj, keys);
|
|
520
|
-
return keys;
|
|
521
|
-
}
|
|
522
|
-
|
|
523
|
-
// Since the regular `Object.prototype.toString` type tests don't work for
|
|
524
|
-
// some types in IE 11, we use a fingerprinting heuristic instead, based
|
|
525
|
-
// on the methods. It's not great, but it's the best we got.
|
|
526
|
-
// The fingerprint method lists are defined below.
|
|
527
|
-
function ie11fingerprint(methods) {
|
|
528
|
-
var length = getLength(methods);
|
|
529
|
-
return function(obj) {
|
|
530
|
-
if (obj == null) return false;
|
|
531
|
-
// `Map`, `WeakMap` and `Set` have no enumerable keys.
|
|
532
|
-
var keys = allKeys(obj);
|
|
533
|
-
if (getLength(keys)) return false;
|
|
534
|
-
for (var i = 0; i < length; i++) {
|
|
535
|
-
if (!isFunction$1(obj[methods[i]])) return false;
|
|
536
|
-
}
|
|
537
|
-
// If we are testing against `WeakMap`, we need to ensure that
|
|
538
|
-
// `obj` doesn't have a `forEach` method in order to distinguish
|
|
539
|
-
// it from a regular `Map`.
|
|
540
|
-
return methods !== weakMapMethods || !isFunction$1(obj[forEachName]);
|
|
541
|
-
};
|
|
542
|
-
}
|
|
543
|
-
|
|
544
|
-
// In the interest of compact minification, we write
|
|
545
|
-
// each string in the fingerprints only once.
|
|
546
|
-
var forEachName = 'forEach',
|
|
547
|
-
hasName = 'has',
|
|
548
|
-
commonInit = ['clear', 'delete'],
|
|
549
|
-
mapTail = ['get', hasName, 'set'];
|
|
550
|
-
|
|
551
|
-
// `Map`, `WeakMap` and `Set` each have slightly different
|
|
552
|
-
// combinations of the above sublists.
|
|
553
|
-
var mapMethods = commonInit.concat(forEachName, mapTail),
|
|
554
|
-
weakMapMethods = commonInit.concat(mapTail),
|
|
555
|
-
setMethods = ['add'].concat(commonInit, forEachName, hasName);
|
|
556
|
-
|
|
557
|
-
var isMap = isIE11 ? ie11fingerprint(mapMethods) : tagTester('Map');
|
|
558
|
-
|
|
559
|
-
var isWeakMap = isIE11 ? ie11fingerprint(weakMapMethods) : tagTester('WeakMap');
|
|
560
|
-
|
|
561
|
-
var isSet = isIE11 ? ie11fingerprint(setMethods) : tagTester('Set');
|
|
562
|
-
|
|
563
|
-
var isWeakSet = tagTester('WeakSet');
|
|
564
|
-
|
|
565
|
-
// Retrieve the values of an object's properties.
|
|
566
|
-
function values(obj) {
|
|
567
|
-
var _keys = keys(obj);
|
|
568
|
-
var length = _keys.length;
|
|
569
|
-
var values = Array(length);
|
|
570
|
-
for (var i = 0; i < length; i++) {
|
|
571
|
-
values[i] = obj[_keys[i]];
|
|
572
|
-
}
|
|
573
|
-
return values;
|
|
574
|
-
}
|
|
575
|
-
|
|
576
|
-
// Convert an object into a list of `[key, value]` pairs.
|
|
577
|
-
// The opposite of `_.object` with one argument.
|
|
578
|
-
function pairs(obj) {
|
|
579
|
-
var _keys = keys(obj);
|
|
580
|
-
var length = _keys.length;
|
|
581
|
-
var pairs = Array(length);
|
|
582
|
-
for (var i = 0; i < length; i++) {
|
|
583
|
-
pairs[i] = [_keys[i], obj[_keys[i]]];
|
|
584
|
-
}
|
|
585
|
-
return pairs;
|
|
586
|
-
}
|
|
587
|
-
|
|
588
|
-
// Invert the keys and values of an object. The values must be serializable.
|
|
589
|
-
function invert(obj) {
|
|
590
|
-
var result = {};
|
|
591
|
-
var _keys = keys(obj);
|
|
592
|
-
for (var i = 0, length = _keys.length; i < length; i++) {
|
|
593
|
-
result[obj[_keys[i]]] = _keys[i];
|
|
594
|
-
}
|
|
595
|
-
return result;
|
|
596
|
-
}
|
|
597
|
-
|
|
598
|
-
// Return a sorted list of the function names available on the object.
|
|
599
|
-
function functions(obj) {
|
|
600
|
-
var names = [];
|
|
601
|
-
for (var key in obj) {
|
|
602
|
-
if (isFunction$1(obj[key])) names.push(key);
|
|
603
|
-
}
|
|
604
|
-
return names.sort();
|
|
605
|
-
}
|
|
606
|
-
|
|
607
|
-
// An internal function for creating assigner functions.
|
|
608
|
-
function createAssigner(keysFunc, defaults) {
|
|
609
|
-
return function(obj) {
|
|
610
|
-
var length = arguments.length;
|
|
611
|
-
if (defaults) obj = Object(obj);
|
|
612
|
-
if (length < 2 || obj == null) return obj;
|
|
613
|
-
for (var index = 1; index < length; index++) {
|
|
614
|
-
var source = arguments[index],
|
|
615
|
-
keys = keysFunc(source),
|
|
616
|
-
l = keys.length;
|
|
617
|
-
for (var i = 0; i < l; i++) {
|
|
618
|
-
var key = keys[i];
|
|
619
|
-
if (!defaults || obj[key] === void 0) obj[key] = source[key];
|
|
620
|
-
}
|
|
621
|
-
}
|
|
622
|
-
return obj;
|
|
623
|
-
};
|
|
624
|
-
}
|
|
625
|
-
|
|
626
|
-
// Extend a given object with all the properties in passed-in object(s).
|
|
627
|
-
var extend = createAssigner(allKeys);
|
|
628
|
-
|
|
629
|
-
// Assigns a given object with all the own properties in the passed-in
|
|
630
|
-
// object(s).
|
|
631
|
-
// (https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/assign)
|
|
632
|
-
var extendOwn = createAssigner(keys);
|
|
633
|
-
|
|
634
|
-
// Fill in a given object with default properties.
|
|
635
|
-
var defaults = createAssigner(allKeys, true);
|
|
636
|
-
|
|
637
|
-
// Create a naked function reference for surrogate-prototype-swapping.
|
|
638
|
-
function ctor() {
|
|
639
|
-
return function(){};
|
|
640
|
-
}
|
|
641
|
-
|
|
642
|
-
// An internal function for creating a new object that inherits from another.
|
|
643
|
-
function baseCreate(prototype) {
|
|
644
|
-
if (!isObject$1(prototype)) return {};
|
|
645
|
-
if (nativeCreate) return nativeCreate(prototype);
|
|
646
|
-
var Ctor = ctor();
|
|
647
|
-
Ctor.prototype = prototype;
|
|
648
|
-
var result = new Ctor;
|
|
649
|
-
Ctor.prototype = null;
|
|
650
|
-
return result;
|
|
651
|
-
}
|
|
652
|
-
|
|
653
|
-
// Creates an object that inherits from the given prototype object.
|
|
654
|
-
// If additional properties are provided then they will be added to the
|
|
655
|
-
// created object.
|
|
656
|
-
function create(prototype, props) {
|
|
657
|
-
var result = baseCreate(prototype);
|
|
658
|
-
if (props) extendOwn(result, props);
|
|
659
|
-
return result;
|
|
660
|
-
}
|
|
661
|
-
|
|
662
|
-
// Create a (shallow-cloned) duplicate of an object.
|
|
663
|
-
function clone(obj) {
|
|
664
|
-
if (!isObject$1(obj)) return obj;
|
|
665
|
-
return isArray(obj) ? obj.slice() : extend({}, obj);
|
|
666
|
-
}
|
|
667
|
-
|
|
668
|
-
// Invokes `interceptor` with the `obj` and then returns `obj`.
|
|
669
|
-
// The primary purpose of this method is to "tap into" a method chain, in
|
|
670
|
-
// order to perform operations on intermediate results within the chain.
|
|
671
|
-
function tap(obj, interceptor) {
|
|
672
|
-
interceptor(obj);
|
|
673
|
-
return obj;
|
|
674
|
-
}
|
|
675
|
-
|
|
676
|
-
// Normalize a (deep) property `path` to array.
|
|
677
|
-
// Like `_.iteratee`, this function can be customized.
|
|
678
|
-
function toPath$1(path) {
|
|
679
|
-
return isArray(path) ? path : [path];
|
|
680
|
-
}
|
|
681
|
-
_$1.toPath = toPath$1;
|
|
682
|
-
|
|
683
|
-
// Internal wrapper for `_.toPath` to enable minification.
|
|
684
|
-
// Similar to `cb` for `_.iteratee`.
|
|
685
|
-
function toPath(path) {
|
|
686
|
-
return _$1.toPath(path);
|
|
687
|
-
}
|
|
688
|
-
|
|
689
|
-
// Internal function to obtain a nested property in `obj` along `path`.
|
|
690
|
-
function deepGet(obj, path) {
|
|
691
|
-
var length = path.length;
|
|
692
|
-
for (var i = 0; i < length; i++) {
|
|
693
|
-
if (obj == null) return void 0;
|
|
694
|
-
obj = obj[path[i]];
|
|
695
|
-
}
|
|
696
|
-
return length ? obj : void 0;
|
|
697
|
-
}
|
|
698
|
-
|
|
699
|
-
// Get the value of the (deep) property on `path` from `object`.
|
|
700
|
-
// If any property in `path` does not exist or if the value is
|
|
701
|
-
// `undefined`, return `defaultValue` instead.
|
|
702
|
-
// The `path` is normalized through `_.toPath`.
|
|
703
|
-
function get(object, path, defaultValue) {
|
|
704
|
-
var value = deepGet(object, toPath(path));
|
|
705
|
-
return isUndefined(value) ? defaultValue : value;
|
|
706
|
-
}
|
|
707
|
-
|
|
708
|
-
// Shortcut function for checking if an object has a given property directly on
|
|
709
|
-
// itself (in other words, not on a prototype). Unlike the internal `has`
|
|
710
|
-
// function, this public version can also traverse nested properties.
|
|
711
|
-
function has(obj, path) {
|
|
712
|
-
path = toPath(path);
|
|
713
|
-
var length = path.length;
|
|
714
|
-
for (var i = 0; i < length; i++) {
|
|
715
|
-
var key = path[i];
|
|
716
|
-
if (!has$1(obj, key)) return false;
|
|
717
|
-
obj = obj[key];
|
|
718
|
-
}
|
|
719
|
-
return !!length;
|
|
720
|
-
}
|
|
721
|
-
|
|
722
|
-
// Keep the identity function around for default iteratees.
|
|
723
|
-
function identity(value) {
|
|
724
|
-
return value;
|
|
725
|
-
}
|
|
726
|
-
|
|
727
|
-
// Returns a predicate for checking whether an object has a given set of
|
|
728
|
-
// `key:value` pairs.
|
|
729
|
-
function matcher(attrs) {
|
|
730
|
-
attrs = extendOwn({}, attrs);
|
|
731
|
-
return function(obj) {
|
|
732
|
-
return isMatch(obj, attrs);
|
|
733
|
-
};
|
|
734
|
-
}
|
|
735
|
-
|
|
736
|
-
// Creates a function that, when passed an object, will traverse that object’s
|
|
737
|
-
// properties down the given `path`, specified as an array of keys or indices.
|
|
738
|
-
function property(path) {
|
|
739
|
-
path = toPath(path);
|
|
740
|
-
return function(obj) {
|
|
741
|
-
return deepGet(obj, path);
|
|
742
|
-
};
|
|
743
|
-
}
|
|
744
|
-
|
|
745
|
-
// Internal function that returns an efficient (for current engines) version
|
|
746
|
-
// of the passed-in callback, to be repeatedly applied in other Underscore
|
|
747
|
-
// functions.
|
|
748
|
-
function optimizeCb(func, context, argCount) {
|
|
749
|
-
if (context === void 0) return func;
|
|
750
|
-
switch (argCount == null ? 3 : argCount) {
|
|
751
|
-
case 1: return function(value) {
|
|
752
|
-
return func.call(context, value);
|
|
753
|
-
};
|
|
754
|
-
// The 2-argument case is omitted because we’re not using it.
|
|
755
|
-
case 3: return function(value, index, collection) {
|
|
756
|
-
return func.call(context, value, index, collection);
|
|
757
|
-
};
|
|
758
|
-
case 4: return function(accumulator, value, index, collection) {
|
|
759
|
-
return func.call(context, accumulator, value, index, collection);
|
|
760
|
-
};
|
|
761
|
-
}
|
|
762
|
-
return function() {
|
|
763
|
-
return func.apply(context, arguments);
|
|
764
|
-
};
|
|
765
|
-
}
|
|
766
|
-
|
|
767
|
-
// An internal function to generate callbacks that can be applied to each
|
|
768
|
-
// element in a collection, returning the desired result — either `_.identity`,
|
|
769
|
-
// an arbitrary callback, a property matcher, or a property accessor.
|
|
770
|
-
function baseIteratee(value, context, argCount) {
|
|
771
|
-
if (value == null) return identity;
|
|
772
|
-
if (isFunction$1(value)) return optimizeCb(value, context, argCount);
|
|
773
|
-
if (isObject$1(value) && !isArray(value)) return matcher(value);
|
|
774
|
-
return property(value);
|
|
775
|
-
}
|
|
776
|
-
|
|
777
|
-
// External wrapper for our callback generator. Users may customize
|
|
778
|
-
// `_.iteratee` if they want additional predicate/iteratee shorthand styles.
|
|
779
|
-
// This abstraction hides the internal-only `argCount` argument.
|
|
780
|
-
function iteratee(value, context) {
|
|
781
|
-
return baseIteratee(value, context, Infinity);
|
|
782
|
-
}
|
|
783
|
-
_$1.iteratee = iteratee;
|
|
784
|
-
|
|
785
|
-
// The function we call internally to generate a callback. It invokes
|
|
786
|
-
// `_.iteratee` if overridden, otherwise `baseIteratee`.
|
|
787
|
-
function cb(value, context, argCount) {
|
|
788
|
-
if (_$1.iteratee !== iteratee) return _$1.iteratee(value, context);
|
|
789
|
-
return baseIteratee(value, context, argCount);
|
|
790
|
-
}
|
|
791
|
-
|
|
792
|
-
// Returns the results of applying the `iteratee` to each element of `obj`.
|
|
793
|
-
// In contrast to `_.map` it returns an object.
|
|
794
|
-
function mapObject$1(obj, iteratee, context) {
|
|
795
|
-
iteratee = cb(iteratee, context);
|
|
796
|
-
var _keys = keys(obj),
|
|
797
|
-
length = _keys.length,
|
|
798
|
-
results = {};
|
|
799
|
-
for (var index = 0; index < length; index++) {
|
|
800
|
-
var currentKey = _keys[index];
|
|
801
|
-
results[currentKey] = iteratee(obj[currentKey], currentKey, obj);
|
|
802
|
-
}
|
|
803
|
-
return results;
|
|
804
|
-
}
|
|
805
|
-
|
|
806
|
-
// Predicate-generating function. Often useful outside of Underscore.
|
|
807
|
-
function noop(){}
|
|
808
|
-
|
|
809
|
-
// Generates a function for a given object that returns a given property.
|
|
810
|
-
function propertyOf(obj) {
|
|
811
|
-
if (obj == null) return noop;
|
|
812
|
-
return function(path) {
|
|
813
|
-
return get(obj, path);
|
|
814
|
-
};
|
|
815
|
-
}
|
|
816
|
-
|
|
817
|
-
// Run a function **n** times.
|
|
818
|
-
function times(n, iteratee, context) {
|
|
819
|
-
var accum = Array(Math.max(0, n));
|
|
820
|
-
iteratee = optimizeCb(iteratee, context, 1);
|
|
821
|
-
for (var i = 0; i < n; i++) accum[i] = iteratee(i);
|
|
822
|
-
return accum;
|
|
823
|
-
}
|
|
824
|
-
|
|
825
|
-
// Return a random integer between `min` and `max` (inclusive).
|
|
826
|
-
function random$1(min, max) {
|
|
827
|
-
if (max == null) {
|
|
828
|
-
max = min;
|
|
829
|
-
min = 0;
|
|
830
|
-
}
|
|
831
|
-
return min + Math.floor(Math.random() * (max - min + 1));
|
|
832
|
-
}
|
|
833
|
-
|
|
834
|
-
// A (possibly faster) way to get the current timestamp as an integer.
|
|
835
|
-
var now = Date.now || function() {
|
|
836
|
-
return new Date().getTime();
|
|
837
|
-
};
|
|
838
|
-
|
|
839
|
-
// Internal helper to generate functions for escaping and unescaping strings
|
|
840
|
-
// to/from HTML interpolation.
|
|
841
|
-
function createEscaper(map) {
|
|
842
|
-
var escaper = function(match) {
|
|
843
|
-
return map[match];
|
|
844
|
-
};
|
|
845
|
-
// Regexes for identifying a key that needs to be escaped.
|
|
846
|
-
var source = '(?:' + keys(map).join('|') + ')';
|
|
847
|
-
var testRegexp = RegExp(source);
|
|
848
|
-
var replaceRegexp = RegExp(source, 'g');
|
|
849
|
-
return function(string) {
|
|
850
|
-
string = string == null ? '' : '' + string;
|
|
851
|
-
return testRegexp.test(string) ? string.replace(replaceRegexp, escaper) : string;
|
|
852
|
-
};
|
|
853
|
-
}
|
|
854
|
-
|
|
855
|
-
// Internal list of HTML entities for escaping.
|
|
856
|
-
var escapeMap = {
|
|
857
|
-
'&': '&',
|
|
858
|
-
'<': '<',
|
|
859
|
-
'>': '>',
|
|
860
|
-
'"': '"',
|
|
861
|
-
"'": ''',
|
|
862
|
-
'`': '`'
|
|
863
|
-
};
|
|
864
|
-
|
|
865
|
-
// Function for escaping strings to HTML interpolation.
|
|
866
|
-
var escape = createEscaper(escapeMap);
|
|
867
|
-
|
|
868
|
-
// Internal list of HTML entities for unescaping.
|
|
869
|
-
var unescapeMap = invert(escapeMap);
|
|
870
|
-
|
|
871
|
-
// Function for unescaping strings from HTML interpolation.
|
|
872
|
-
var unescape = createEscaper(unescapeMap);
|
|
873
|
-
|
|
874
|
-
// By default, Underscore uses ERB-style template delimiters. Change the
|
|
875
|
-
// following template settings to use alternative delimiters.
|
|
876
|
-
var templateSettings = _$1.templateSettings = {
|
|
877
|
-
evaluate: /<%([\s\S]+?)%>/g,
|
|
878
|
-
interpolate: /<%=([\s\S]+?)%>/g,
|
|
879
|
-
escape: /<%-([\s\S]+?)%>/g
|
|
880
|
-
};
|
|
881
|
-
|
|
882
|
-
// When customizing `_.templateSettings`, if you don't want to define an
|
|
883
|
-
// interpolation, evaluation or escaping regex, we need one that is
|
|
884
|
-
// guaranteed not to match.
|
|
885
|
-
var noMatch = /(.)^/;
|
|
886
|
-
|
|
887
|
-
// Certain characters need to be escaped so that they can be put into a
|
|
888
|
-
// string literal.
|
|
889
|
-
var escapes = {
|
|
890
|
-
"'": "'",
|
|
891
|
-
'\\': '\\',
|
|
892
|
-
'\r': 'r',
|
|
893
|
-
'\n': 'n',
|
|
894
|
-
'\u2028': 'u2028',
|
|
895
|
-
'\u2029': 'u2029'
|
|
896
|
-
};
|
|
897
|
-
|
|
898
|
-
var escapeRegExp = /\\|'|\r|\n|\u2028|\u2029/g;
|
|
899
|
-
|
|
900
|
-
function escapeChar(match) {
|
|
901
|
-
return '\\' + escapes[match];
|
|
902
|
-
}
|
|
903
|
-
|
|
904
|
-
// In order to prevent third-party code injection through
|
|
905
|
-
// `_.templateSettings.variable`, we test it against the following regular
|
|
906
|
-
// expression. It is intentionally a bit more liberal than just matching valid
|
|
907
|
-
// identifiers, but still prevents possible loopholes through defaults or
|
|
908
|
-
// destructuring assignment.
|
|
909
|
-
var bareIdentifier = /^\s*(\w|\$)+\s*$/;
|
|
910
|
-
|
|
911
|
-
// JavaScript micro-templating, similar to John Resig's implementation.
|
|
912
|
-
// Underscore templating handles arbitrary delimiters, preserves whitespace,
|
|
913
|
-
// and correctly escapes quotes within interpolated code.
|
|
914
|
-
// NB: `oldSettings` only exists for backwards compatibility.
|
|
915
|
-
function template(text, settings, oldSettings) {
|
|
916
|
-
if (!settings && oldSettings) settings = oldSettings;
|
|
917
|
-
settings = defaults({}, settings, _$1.templateSettings);
|
|
918
|
-
|
|
919
|
-
// Combine delimiters into one regular expression via alternation.
|
|
920
|
-
var matcher = RegExp([
|
|
921
|
-
(settings.escape || noMatch).source,
|
|
922
|
-
(settings.interpolate || noMatch).source,
|
|
923
|
-
(settings.evaluate || noMatch).source
|
|
924
|
-
].join('|') + '|$', 'g');
|
|
925
|
-
|
|
926
|
-
// Compile the template source, escaping string literals appropriately.
|
|
927
|
-
var index = 0;
|
|
928
|
-
var source = "__p+='";
|
|
929
|
-
text.replace(matcher, function(match, escape, interpolate, evaluate, offset) {
|
|
930
|
-
source += text.slice(index, offset).replace(escapeRegExp, escapeChar);
|
|
931
|
-
index = offset + match.length;
|
|
932
|
-
|
|
933
|
-
if (escape) {
|
|
934
|
-
source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'";
|
|
935
|
-
} else if (interpolate) {
|
|
936
|
-
source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'";
|
|
937
|
-
} else if (evaluate) {
|
|
938
|
-
source += "';\n" + evaluate + "\n__p+='";
|
|
939
|
-
}
|
|
940
|
-
|
|
941
|
-
// Adobe VMs need the match returned to produce the correct offset.
|
|
942
|
-
return match;
|
|
943
|
-
});
|
|
944
|
-
source += "';\n";
|
|
945
|
-
|
|
946
|
-
var argument = settings.variable;
|
|
947
|
-
if (argument) {
|
|
948
|
-
// Insure against third-party code injection. (CVE-2021-23358)
|
|
949
|
-
if (!bareIdentifier.test(argument)) throw new Error(
|
|
950
|
-
'variable is not a bare identifier: ' + argument
|
|
951
|
-
);
|
|
952
|
-
} else {
|
|
953
|
-
// If a variable is not specified, place data values in local scope.
|
|
954
|
-
source = 'with(obj||{}){\n' + source + '}\n';
|
|
955
|
-
argument = 'obj';
|
|
956
|
-
}
|
|
957
|
-
|
|
958
|
-
source = "var __t,__p='',__j=Array.prototype.join," +
|
|
959
|
-
"print=function(){__p+=__j.call(arguments,'');};\n" +
|
|
960
|
-
source + 'return __p;\n';
|
|
961
|
-
|
|
962
|
-
var render;
|
|
963
|
-
try {
|
|
964
|
-
render = new Function(argument, '_', source);
|
|
965
|
-
} catch (e) {
|
|
966
|
-
e.source = source;
|
|
967
|
-
throw e;
|
|
968
|
-
}
|
|
969
|
-
|
|
970
|
-
var template = function(data) {
|
|
971
|
-
return render.call(this, data, _$1);
|
|
972
|
-
};
|
|
973
|
-
|
|
974
|
-
// Provide the compiled source as a convenience for precompilation.
|
|
975
|
-
template.source = 'function(' + argument + '){\n' + source + '}';
|
|
976
|
-
|
|
977
|
-
return template;
|
|
978
|
-
}
|
|
979
|
-
|
|
980
|
-
// Traverses the children of `obj` along `path`. If a child is a function, it
|
|
981
|
-
// is invoked with its parent as context. Returns the value of the final
|
|
982
|
-
// child, or `fallback` if any child is undefined.
|
|
983
|
-
function result(obj, path, fallback) {
|
|
984
|
-
path = toPath(path);
|
|
985
|
-
var length = path.length;
|
|
986
|
-
if (!length) {
|
|
987
|
-
return isFunction$1(fallback) ? fallback.call(obj) : fallback;
|
|
988
|
-
}
|
|
989
|
-
for (var i = 0; i < length; i++) {
|
|
990
|
-
var prop = obj == null ? void 0 : obj[path[i]];
|
|
991
|
-
if (prop === void 0) {
|
|
992
|
-
prop = fallback;
|
|
993
|
-
i = length; // Ensure we don't continue iterating.
|
|
994
|
-
}
|
|
995
|
-
obj = isFunction$1(prop) ? prop.call(obj) : prop;
|
|
996
|
-
}
|
|
997
|
-
return obj;
|
|
998
|
-
}
|
|
999
|
-
|
|
1000
|
-
// Generate a unique integer id (unique within the entire client session).
|
|
1001
|
-
// Useful for temporary DOM ids.
|
|
1002
|
-
var idCounter = 0;
|
|
1003
|
-
function uniqueId(prefix) {
|
|
1004
|
-
var id = ++idCounter + '';
|
|
1005
|
-
return prefix ? prefix + id : id;
|
|
1006
|
-
}
|
|
1007
|
-
|
|
1008
|
-
// Start chaining a wrapped Underscore object.
|
|
1009
|
-
function chain(obj) {
|
|
1010
|
-
var instance = _$1(obj);
|
|
1011
|
-
instance._chain = true;
|
|
1012
|
-
return instance;
|
|
1013
|
-
}
|
|
1014
|
-
|
|
1015
|
-
// Internal function to execute `sourceFunc` bound to `context` with optional
|
|
1016
|
-
// `args`. Determines whether to execute a function as a constructor or as a
|
|
1017
|
-
// normal function.
|
|
1018
|
-
function executeBound(sourceFunc, boundFunc, context, callingContext, args) {
|
|
1019
|
-
if (!(callingContext instanceof boundFunc)) return sourceFunc.apply(context, args);
|
|
1020
|
-
var self = baseCreate(sourceFunc.prototype);
|
|
1021
|
-
var result = sourceFunc.apply(self, args);
|
|
1022
|
-
if (isObject$1(result)) return result;
|
|
1023
|
-
return self;
|
|
1024
|
-
}
|
|
1025
|
-
|
|
1026
|
-
// Partially apply a function by creating a version that has had some of its
|
|
1027
|
-
// arguments pre-filled, without changing its dynamic `this` context. `_` acts
|
|
1028
|
-
// as a placeholder by default, allowing any combination of arguments to be
|
|
1029
|
-
// pre-filled. Set `_.partial.placeholder` for a custom placeholder argument.
|
|
1030
|
-
var partial = restArguments(function(func, boundArgs) {
|
|
1031
|
-
var placeholder = partial.placeholder;
|
|
1032
|
-
var bound = function() {
|
|
1033
|
-
var position = 0, length = boundArgs.length;
|
|
1034
|
-
var args = Array(length);
|
|
1035
|
-
for (var i = 0; i < length; i++) {
|
|
1036
|
-
args[i] = boundArgs[i] === placeholder ? arguments[position++] : boundArgs[i];
|
|
1037
|
-
}
|
|
1038
|
-
while (position < arguments.length) args.push(arguments[position++]);
|
|
1039
|
-
return executeBound(func, bound, this, this, args);
|
|
1040
|
-
};
|
|
1041
|
-
return bound;
|
|
1042
|
-
});
|
|
1043
|
-
|
|
1044
|
-
partial.placeholder = _$1;
|
|
1045
|
-
|
|
1046
|
-
// Create a function bound to a given object (assigning `this`, and arguments,
|
|
1047
|
-
// optionally).
|
|
1048
|
-
var bind = restArguments(function(func, context, args) {
|
|
1049
|
-
if (!isFunction$1(func)) throw new TypeError('Bind must be called on a function');
|
|
1050
|
-
var bound = restArguments(function(callArgs) {
|
|
1051
|
-
return executeBound(func, bound, context, this, args.concat(callArgs));
|
|
1052
|
-
});
|
|
1053
|
-
return bound;
|
|
1054
|
-
});
|
|
1055
|
-
|
|
1056
|
-
// Internal helper for collection methods to determine whether a collection
|
|
1057
|
-
// should be iterated as an array or as an object.
|
|
1058
|
-
// Related: https://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength
|
|
1059
|
-
// Avoids a very nasty iOS 8 JIT bug on ARM-64. #2094
|
|
1060
|
-
var isArrayLike = createSizePropertyCheck(getLength);
|
|
1061
|
-
|
|
1062
|
-
// Internal implementation of a recursive `flatten` function.
|
|
1063
|
-
function flatten$1(input, depth, strict, output) {
|
|
1064
|
-
output = output || [];
|
|
1065
|
-
if (!depth && depth !== 0) {
|
|
1066
|
-
depth = Infinity;
|
|
1067
|
-
} else if (depth <= 0) {
|
|
1068
|
-
return output.concat(input);
|
|
1069
|
-
}
|
|
1070
|
-
var idx = output.length;
|
|
1071
|
-
for (var i = 0, length = getLength(input); i < length; i++) {
|
|
1072
|
-
var value = input[i];
|
|
1073
|
-
if (isArrayLike(value) && (isArray(value) || isArguments$1(value))) {
|
|
1074
|
-
// Flatten current level of array or arguments object.
|
|
1075
|
-
if (depth > 1) {
|
|
1076
|
-
flatten$1(value, depth - 1, strict, output);
|
|
1077
|
-
idx = output.length;
|
|
1078
|
-
} else {
|
|
1079
|
-
var j = 0, len = value.length;
|
|
1080
|
-
while (j < len) output[idx++] = value[j++];
|
|
1081
|
-
}
|
|
1082
|
-
} else if (!strict) {
|
|
1083
|
-
output[idx++] = value;
|
|
1084
|
-
}
|
|
1085
|
-
}
|
|
1086
|
-
return output;
|
|
1087
|
-
}
|
|
1088
|
-
|
|
1089
|
-
// Bind a number of an object's methods to that object. Remaining arguments
|
|
1090
|
-
// are the method names to be bound. Useful for ensuring that all callbacks
|
|
1091
|
-
// defined on an object belong to it.
|
|
1092
|
-
var bindAll = restArguments(function(obj, keys) {
|
|
1093
|
-
keys = flatten$1(keys, false, false);
|
|
1094
|
-
var index = keys.length;
|
|
1095
|
-
if (index < 1) throw new Error('bindAll must be passed function names');
|
|
1096
|
-
while (index--) {
|
|
1097
|
-
var key = keys[index];
|
|
1098
|
-
obj[key] = bind(obj[key], obj);
|
|
1099
|
-
}
|
|
1100
|
-
return obj;
|
|
1101
|
-
});
|
|
1102
|
-
|
|
1103
|
-
// Memoize an expensive function by storing its results.
|
|
1104
|
-
function memoize(func, hasher) {
|
|
1105
|
-
var memoize = function(key) {
|
|
1106
|
-
var cache = memoize.cache;
|
|
1107
|
-
var address = '' + (hasher ? hasher.apply(this, arguments) : key);
|
|
1108
|
-
if (!has$1(cache, address)) cache[address] = func.apply(this, arguments);
|
|
1109
|
-
return cache[address];
|
|
1110
|
-
};
|
|
1111
|
-
memoize.cache = {};
|
|
1112
|
-
return memoize;
|
|
1113
|
-
}
|
|
1114
|
-
|
|
1115
|
-
// Delays a function for the given number of milliseconds, and then calls
|
|
1116
|
-
// it with the arguments supplied.
|
|
1117
|
-
var delay = restArguments(function(func, wait, args) {
|
|
1118
|
-
return setTimeout(function() {
|
|
1119
|
-
return func.apply(null, args);
|
|
1120
|
-
}, wait);
|
|
1121
|
-
});
|
|
1122
|
-
|
|
1123
|
-
// Defers a function, scheduling it to run after the current call stack has
|
|
1124
|
-
// cleared.
|
|
1125
|
-
var defer = partial(delay, _$1, 1);
|
|
1126
|
-
|
|
1127
|
-
// Returns a function, that, when invoked, will only be triggered at most once
|
|
1128
|
-
// during a given window of time. Normally, the throttled function will run
|
|
1129
|
-
// as much as it can, without ever going more than once per `wait` duration;
|
|
1130
|
-
// but if you'd like to disable the execution on the leading edge, pass
|
|
1131
|
-
// `{leading: false}`. To disable execution on the trailing edge, ditto.
|
|
1132
|
-
function throttle(func, wait, options) {
|
|
1133
|
-
var timeout, context, args, result;
|
|
1134
|
-
var previous = 0;
|
|
1135
|
-
if (!options) options = {};
|
|
1136
|
-
|
|
1137
|
-
var later = function() {
|
|
1138
|
-
previous = options.leading === false ? 0 : now();
|
|
1139
|
-
timeout = null;
|
|
1140
|
-
result = func.apply(context, args);
|
|
1141
|
-
if (!timeout) context = args = null;
|
|
1142
|
-
};
|
|
1143
|
-
|
|
1144
|
-
var throttled = function() {
|
|
1145
|
-
var _now = now();
|
|
1146
|
-
if (!previous && options.leading === false) previous = _now;
|
|
1147
|
-
var remaining = wait - (_now - previous);
|
|
1148
|
-
context = this;
|
|
1149
|
-
args = arguments;
|
|
1150
|
-
if (remaining <= 0 || remaining > wait) {
|
|
1151
|
-
if (timeout) {
|
|
1152
|
-
clearTimeout(timeout);
|
|
1153
|
-
timeout = null;
|
|
1154
|
-
}
|
|
1155
|
-
previous = _now;
|
|
1156
|
-
result = func.apply(context, args);
|
|
1157
|
-
if (!timeout) context = args = null;
|
|
1158
|
-
} else if (!timeout && options.trailing !== false) {
|
|
1159
|
-
timeout = setTimeout(later, remaining);
|
|
1160
|
-
}
|
|
1161
|
-
return result;
|
|
1162
|
-
};
|
|
1163
|
-
|
|
1164
|
-
throttled.cancel = function() {
|
|
1165
|
-
clearTimeout(timeout);
|
|
1166
|
-
previous = 0;
|
|
1167
|
-
timeout = context = args = null;
|
|
1168
|
-
};
|
|
1169
|
-
|
|
1170
|
-
return throttled;
|
|
1171
|
-
}
|
|
1172
|
-
|
|
1173
|
-
// When a sequence of calls of the returned function ends, the argument
|
|
1174
|
-
// function is triggered. The end of a sequence is defined by the `wait`
|
|
1175
|
-
// parameter. If `immediate` is passed, the argument function will be
|
|
1176
|
-
// triggered at the beginning of the sequence instead of at the end.
|
|
1177
|
-
function debounce(func, wait, immediate) {
|
|
1178
|
-
var timeout, previous, args, result, context;
|
|
1179
|
-
|
|
1180
|
-
var later = function() {
|
|
1181
|
-
var passed = now() - previous;
|
|
1182
|
-
if (wait > passed) {
|
|
1183
|
-
timeout = setTimeout(later, wait - passed);
|
|
1184
|
-
} else {
|
|
1185
|
-
timeout = null;
|
|
1186
|
-
if (!immediate) result = func.apply(context, args);
|
|
1187
|
-
// This check is needed because `func` can recursively invoke `debounced`.
|
|
1188
|
-
if (!timeout) args = context = null;
|
|
1189
|
-
}
|
|
1190
|
-
};
|
|
1191
|
-
|
|
1192
|
-
var debounced = restArguments(function(_args) {
|
|
1193
|
-
context = this;
|
|
1194
|
-
args = _args;
|
|
1195
|
-
previous = now();
|
|
1196
|
-
if (!timeout) {
|
|
1197
|
-
timeout = setTimeout(later, wait);
|
|
1198
|
-
if (immediate) result = func.apply(context, args);
|
|
1199
|
-
}
|
|
1200
|
-
return result;
|
|
1201
|
-
});
|
|
1202
|
-
|
|
1203
|
-
debounced.cancel = function() {
|
|
1204
|
-
clearTimeout(timeout);
|
|
1205
|
-
timeout = args = context = null;
|
|
1206
|
-
};
|
|
1207
|
-
|
|
1208
|
-
return debounced;
|
|
1209
|
-
}
|
|
1210
|
-
|
|
1211
|
-
// Returns the first function passed as an argument to the second,
|
|
1212
|
-
// allowing you to adjust arguments, run code before and after, and
|
|
1213
|
-
// conditionally execute the original function.
|
|
1214
|
-
function wrap(func, wrapper) {
|
|
1215
|
-
return partial(wrapper, func);
|
|
1216
|
-
}
|
|
1217
|
-
|
|
1218
|
-
// Returns a negated version of the passed-in predicate.
|
|
1219
|
-
function negate(predicate) {
|
|
1220
|
-
return function() {
|
|
1221
|
-
return !predicate.apply(this, arguments);
|
|
1222
|
-
};
|
|
1223
|
-
}
|
|
1224
|
-
|
|
1225
|
-
// Returns a function that is the composition of a list of functions, each
|
|
1226
|
-
// consuming the return value of the function that follows.
|
|
1227
|
-
function compose() {
|
|
1228
|
-
var args = arguments;
|
|
1229
|
-
var start = args.length - 1;
|
|
1230
|
-
return function() {
|
|
1231
|
-
var i = start;
|
|
1232
|
-
var result = args[start].apply(this, arguments);
|
|
1233
|
-
while (i--) result = args[i].call(this, result);
|
|
1234
|
-
return result;
|
|
1235
|
-
};
|
|
1236
|
-
}
|
|
1237
|
-
|
|
1238
|
-
// Returns a function that will only be executed on and after the Nth call.
|
|
1239
|
-
function after(times, func) {
|
|
1240
|
-
return function() {
|
|
1241
|
-
if (--times < 1) {
|
|
1242
|
-
return func.apply(this, arguments);
|
|
1243
|
-
}
|
|
1244
|
-
};
|
|
1245
|
-
}
|
|
1246
|
-
|
|
1247
|
-
// Returns a function that will only be executed up to (but not including) the
|
|
1248
|
-
// Nth call.
|
|
1249
|
-
function before(times, func) {
|
|
1250
|
-
var memo;
|
|
1251
|
-
return function() {
|
|
1252
|
-
if (--times > 0) {
|
|
1253
|
-
memo = func.apply(this, arguments);
|
|
1254
|
-
}
|
|
1255
|
-
if (times <= 1) func = null;
|
|
1256
|
-
return memo;
|
|
1257
|
-
};
|
|
1258
|
-
}
|
|
1259
|
-
|
|
1260
|
-
// Returns a function that will be executed at most one time, no matter how
|
|
1261
|
-
// often you call it. Useful for lazy initialization.
|
|
1262
|
-
var once = partial(before, 2);
|
|
1263
|
-
|
|
1264
|
-
// Returns the first key on an object that passes a truth test.
|
|
1265
|
-
function findKey(obj, predicate, context) {
|
|
1266
|
-
predicate = cb(predicate, context);
|
|
1267
|
-
var _keys = keys(obj), key;
|
|
1268
|
-
for (var i = 0, length = _keys.length; i < length; i++) {
|
|
1269
|
-
key = _keys[i];
|
|
1270
|
-
if (predicate(obj[key], key, obj)) return key;
|
|
1271
|
-
}
|
|
1272
|
-
}
|
|
1273
|
-
|
|
1274
|
-
// Internal function to generate `_.findIndex` and `_.findLastIndex`.
|
|
1275
|
-
function createPredicateIndexFinder(dir) {
|
|
1276
|
-
return function(array, predicate, context) {
|
|
1277
|
-
predicate = cb(predicate, context);
|
|
1278
|
-
var length = getLength(array);
|
|
1279
|
-
var index = dir > 0 ? 0 : length - 1;
|
|
1280
|
-
for (; index >= 0 && index < length; index += dir) {
|
|
1281
|
-
if (predicate(array[index], index, array)) return index;
|
|
1282
|
-
}
|
|
1283
|
-
return -1;
|
|
1284
|
-
};
|
|
1285
|
-
}
|
|
1286
|
-
|
|
1287
|
-
// Returns the first index on an array-like that passes a truth test.
|
|
1288
|
-
var findIndex = createPredicateIndexFinder(1);
|
|
1289
|
-
|
|
1290
|
-
// Returns the last index on an array-like that passes a truth test.
|
|
1291
|
-
var findLastIndex = createPredicateIndexFinder(-1);
|
|
1292
|
-
|
|
1293
|
-
// Use a comparator function to figure out the smallest index at which
|
|
1294
|
-
// an object should be inserted so as to maintain order. Uses binary search.
|
|
1295
|
-
function sortedIndex(array, obj, iteratee, context) {
|
|
1296
|
-
iteratee = cb(iteratee, context, 1);
|
|
1297
|
-
var value = iteratee(obj);
|
|
1298
|
-
var low = 0, high = getLength(array);
|
|
1299
|
-
while (low < high) {
|
|
1300
|
-
var mid = Math.floor((low + high) / 2);
|
|
1301
|
-
if (iteratee(array[mid]) < value) low = mid + 1; else high = mid;
|
|
1302
|
-
}
|
|
1303
|
-
return low;
|
|
1304
|
-
}
|
|
1305
|
-
|
|
1306
|
-
// Internal function to generate the `_.indexOf` and `_.lastIndexOf` functions.
|
|
1307
|
-
function createIndexFinder(dir, predicateFind, sortedIndex) {
|
|
1308
|
-
return function(array, item, idx) {
|
|
1309
|
-
var i = 0, length = getLength(array);
|
|
1310
|
-
if (typeof idx == 'number') {
|
|
1311
|
-
if (dir > 0) {
|
|
1312
|
-
i = idx >= 0 ? idx : Math.max(idx + length, i);
|
|
1313
|
-
} else {
|
|
1314
|
-
length = idx >= 0 ? Math.min(idx + 1, length) : idx + length + 1;
|
|
1315
|
-
}
|
|
1316
|
-
} else if (sortedIndex && idx && length) {
|
|
1317
|
-
idx = sortedIndex(array, item);
|
|
1318
|
-
return array[idx] === item ? idx : -1;
|
|
1319
|
-
}
|
|
1320
|
-
if (item !== item) {
|
|
1321
|
-
idx = predicateFind(slice.call(array, i, length), isNaN$1);
|
|
1322
|
-
return idx >= 0 ? idx + i : -1;
|
|
1323
|
-
}
|
|
1324
|
-
for (idx = dir > 0 ? i : length - 1; idx >= 0 && idx < length; idx += dir) {
|
|
1325
|
-
if (array[idx] === item) return idx;
|
|
1326
|
-
}
|
|
1327
|
-
return -1;
|
|
1328
|
-
};
|
|
1329
|
-
}
|
|
1330
|
-
|
|
1331
|
-
// Return the position of the first occurrence of an item in an array,
|
|
1332
|
-
// or -1 if the item is not included in the array.
|
|
1333
|
-
// If the array is large and already in sort order, pass `true`
|
|
1334
|
-
// for **isSorted** to use binary search.
|
|
1335
|
-
var indexOf = createIndexFinder(1, findIndex, sortedIndex);
|
|
1336
|
-
|
|
1337
|
-
// Return the position of the last occurrence of an item in an array,
|
|
1338
|
-
// or -1 if the item is not included in the array.
|
|
1339
|
-
var lastIndexOf = createIndexFinder(-1, findLastIndex);
|
|
1340
|
-
|
|
1341
|
-
// Return the first value which passes a truth test.
|
|
1342
|
-
function find(obj, predicate, context) {
|
|
1343
|
-
var keyFinder = isArrayLike(obj) ? findIndex : findKey;
|
|
1344
|
-
var key = keyFinder(obj, predicate, context);
|
|
1345
|
-
if (key !== void 0 && key !== -1) return obj[key];
|
|
1346
|
-
}
|
|
1347
|
-
|
|
1348
|
-
// Convenience version of a common use case of `_.find`: getting the first
|
|
1349
|
-
// object containing specific `key:value` pairs.
|
|
1350
|
-
function findWhere(obj, attrs) {
|
|
1351
|
-
return find(obj, matcher(attrs));
|
|
1352
|
-
}
|
|
1353
|
-
|
|
1354
|
-
// The cornerstone for collection functions, an `each`
|
|
1355
|
-
// implementation, aka `forEach`.
|
|
1356
|
-
// Handles raw objects in addition to array-likes. Treats all
|
|
1357
|
-
// sparse array-likes as if they were dense.
|
|
1358
|
-
function each(obj, iteratee, context) {
|
|
1359
|
-
iteratee = optimizeCb(iteratee, context);
|
|
1360
|
-
var i, length;
|
|
1361
|
-
if (isArrayLike(obj)) {
|
|
1362
|
-
for (i = 0, length = obj.length; i < length; i++) {
|
|
1363
|
-
iteratee(obj[i], i, obj);
|
|
1364
|
-
}
|
|
1365
|
-
} else {
|
|
1366
|
-
var _keys = keys(obj);
|
|
1367
|
-
for (i = 0, length = _keys.length; i < length; i++) {
|
|
1368
|
-
iteratee(obj[_keys[i]], _keys[i], obj);
|
|
1369
|
-
}
|
|
1370
|
-
}
|
|
1371
|
-
return obj;
|
|
1372
|
-
}
|
|
1373
|
-
|
|
1374
|
-
// Return the results of applying the iteratee to each element.
|
|
1375
|
-
function map(obj, iteratee, context) {
|
|
1376
|
-
iteratee = cb(iteratee, context);
|
|
1377
|
-
var _keys = !isArrayLike(obj) && keys(obj),
|
|
1378
|
-
length = (_keys || obj).length,
|
|
1379
|
-
results = Array(length);
|
|
1380
|
-
for (var index = 0; index < length; index++) {
|
|
1381
|
-
var currentKey = _keys ? _keys[index] : index;
|
|
1382
|
-
results[index] = iteratee(obj[currentKey], currentKey, obj);
|
|
1383
|
-
}
|
|
1384
|
-
return results;
|
|
1385
|
-
}
|
|
1386
|
-
|
|
1387
|
-
// Internal helper to create a reducing function, iterating left or right.
|
|
1388
|
-
function createReduce(dir) {
|
|
1389
|
-
// Wrap code that reassigns argument variables in a separate function than
|
|
1390
|
-
// the one that accesses `arguments.length` to avoid a perf hit. (#1991)
|
|
1391
|
-
var reducer = function(obj, iteratee, memo, initial) {
|
|
1392
|
-
var _keys = !isArrayLike(obj) && keys(obj),
|
|
1393
|
-
length = (_keys || obj).length,
|
|
1394
|
-
index = dir > 0 ? 0 : length - 1;
|
|
1395
|
-
if (!initial) {
|
|
1396
|
-
memo = obj[_keys ? _keys[index] : index];
|
|
1397
|
-
index += dir;
|
|
1398
|
-
}
|
|
1399
|
-
for (; index >= 0 && index < length; index += dir) {
|
|
1400
|
-
var currentKey = _keys ? _keys[index] : index;
|
|
1401
|
-
memo = iteratee(memo, obj[currentKey], currentKey, obj);
|
|
1402
|
-
}
|
|
1403
|
-
return memo;
|
|
1404
|
-
};
|
|
1405
|
-
|
|
1406
|
-
return function(obj, iteratee, memo, context) {
|
|
1407
|
-
var initial = arguments.length >= 3;
|
|
1408
|
-
return reducer(obj, optimizeCb(iteratee, context, 4), memo, initial);
|
|
1409
|
-
};
|
|
1410
|
-
}
|
|
1411
|
-
|
|
1412
|
-
// **Reduce** builds up a single result from a list of values, aka `inject`,
|
|
1413
|
-
// or `foldl`.
|
|
1414
|
-
var reduce = createReduce(1);
|
|
1415
|
-
|
|
1416
|
-
// The right-associative version of reduce, also known as `foldr`.
|
|
1417
|
-
var reduceRight = createReduce(-1);
|
|
1418
|
-
|
|
1419
|
-
// Return all the elements that pass a truth test.
|
|
1420
|
-
function filter(obj, predicate, context) {
|
|
1421
|
-
var results = [];
|
|
1422
|
-
predicate = cb(predicate, context);
|
|
1423
|
-
each(obj, function(value, index, list) {
|
|
1424
|
-
if (predicate(value, index, list)) results.push(value);
|
|
1425
|
-
});
|
|
1426
|
-
return results;
|
|
1427
|
-
}
|
|
1428
|
-
|
|
1429
|
-
// Return all the elements for which a truth test fails.
|
|
1430
|
-
function reject(obj, predicate, context) {
|
|
1431
|
-
return filter(obj, negate(cb(predicate)), context);
|
|
1432
|
-
}
|
|
1433
|
-
|
|
1434
|
-
// Determine whether all of the elements pass a truth test.
|
|
1435
|
-
function every(obj, predicate, context) {
|
|
1436
|
-
predicate = cb(predicate, context);
|
|
1437
|
-
var _keys = !isArrayLike(obj) && keys(obj),
|
|
1438
|
-
length = (_keys || obj).length;
|
|
1439
|
-
for (var index = 0; index < length; index++) {
|
|
1440
|
-
var currentKey = _keys ? _keys[index] : index;
|
|
1441
|
-
if (!predicate(obj[currentKey], currentKey, obj)) return false;
|
|
1442
|
-
}
|
|
1443
|
-
return true;
|
|
1444
|
-
}
|
|
1445
|
-
|
|
1446
|
-
// Determine if at least one element in the object passes a truth test.
|
|
1447
|
-
function some(obj, predicate, context) {
|
|
1448
|
-
predicate = cb(predicate, context);
|
|
1449
|
-
var _keys = !isArrayLike(obj) && keys(obj),
|
|
1450
|
-
length = (_keys || obj).length;
|
|
1451
|
-
for (var index = 0; index < length; index++) {
|
|
1452
|
-
var currentKey = _keys ? _keys[index] : index;
|
|
1453
|
-
if (predicate(obj[currentKey], currentKey, obj)) return true;
|
|
1454
|
-
}
|
|
1455
|
-
return false;
|
|
1456
|
-
}
|
|
1457
|
-
|
|
1458
|
-
// Determine if the array or object contains a given item (using `===`).
|
|
1459
|
-
function contains(obj, item, fromIndex, guard) {
|
|
1460
|
-
if (!isArrayLike(obj)) obj = values(obj);
|
|
1461
|
-
if (typeof fromIndex != 'number' || guard) fromIndex = 0;
|
|
1462
|
-
return indexOf(obj, item, fromIndex) >= 0;
|
|
1463
|
-
}
|
|
1464
|
-
|
|
1465
|
-
// Invoke a method (with arguments) on every item in a collection.
|
|
1466
|
-
var invoke = restArguments(function(obj, path, args) {
|
|
1467
|
-
var contextPath, func;
|
|
1468
|
-
if (isFunction$1(path)) {
|
|
1469
|
-
func = path;
|
|
1470
|
-
} else {
|
|
1471
|
-
path = toPath(path);
|
|
1472
|
-
contextPath = path.slice(0, -1);
|
|
1473
|
-
path = path[path.length - 1];
|
|
1474
|
-
}
|
|
1475
|
-
return map(obj, function(context) {
|
|
1476
|
-
var method = func;
|
|
1477
|
-
if (!method) {
|
|
1478
|
-
if (contextPath && contextPath.length) {
|
|
1479
|
-
context = deepGet(context, contextPath);
|
|
1480
|
-
}
|
|
1481
|
-
if (context == null) return void 0;
|
|
1482
|
-
method = context[path];
|
|
1483
|
-
}
|
|
1484
|
-
return method == null ? method : method.apply(context, args);
|
|
1485
|
-
});
|
|
1486
|
-
});
|
|
1487
|
-
|
|
1488
|
-
// Convenience version of a common use case of `_.map`: fetching a property.
|
|
1489
|
-
function pluck$1(obj, key) {
|
|
1490
|
-
return map(obj, property(key));
|
|
1491
|
-
}
|
|
1492
|
-
|
|
1493
|
-
// Convenience version of a common use case of `_.filter`: selecting only
|
|
1494
|
-
// objects containing specific `key:value` pairs.
|
|
1495
|
-
function where(obj, attrs) {
|
|
1496
|
-
return filter(obj, matcher(attrs));
|
|
1497
|
-
}
|
|
1498
|
-
|
|
1499
|
-
// Return the maximum element (or element-based computation).
|
|
1500
|
-
function max(obj, iteratee, context) {
|
|
1501
|
-
var result = -Infinity, lastComputed = -Infinity,
|
|
1502
|
-
value, computed;
|
|
1503
|
-
if (iteratee == null || (typeof iteratee == 'number' && typeof obj[0] != 'object' && obj != null)) {
|
|
1504
|
-
obj = isArrayLike(obj) ? obj : values(obj);
|
|
1505
|
-
for (var i = 0, length = obj.length; i < length; i++) {
|
|
1506
|
-
value = obj[i];
|
|
1507
|
-
if (value != null && value > result) {
|
|
1508
|
-
result = value;
|
|
1509
|
-
}
|
|
1510
|
-
}
|
|
1511
|
-
} else {
|
|
1512
|
-
iteratee = cb(iteratee, context);
|
|
1513
|
-
each(obj, function(v, index, list) {
|
|
1514
|
-
computed = iteratee(v, index, list);
|
|
1515
|
-
if (computed > lastComputed || (computed === -Infinity && result === -Infinity)) {
|
|
1516
|
-
result = v;
|
|
1517
|
-
lastComputed = computed;
|
|
1518
|
-
}
|
|
1519
|
-
});
|
|
1520
|
-
}
|
|
1521
|
-
return result;
|
|
1522
|
-
}
|
|
1523
|
-
|
|
1524
|
-
// Return the minimum element (or element-based computation).
|
|
1525
|
-
function min(obj, iteratee, context) {
|
|
1526
|
-
var result = Infinity, lastComputed = Infinity,
|
|
1527
|
-
value, computed;
|
|
1528
|
-
if (iteratee == null || (typeof iteratee == 'number' && typeof obj[0] != 'object' && obj != null)) {
|
|
1529
|
-
obj = isArrayLike(obj) ? obj : values(obj);
|
|
1530
|
-
for (var i = 0, length = obj.length; i < length; i++) {
|
|
1531
|
-
value = obj[i];
|
|
1532
|
-
if (value != null && value < result) {
|
|
1533
|
-
result = value;
|
|
1534
|
-
}
|
|
1535
|
-
}
|
|
1536
|
-
} else {
|
|
1537
|
-
iteratee = cb(iteratee, context);
|
|
1538
|
-
each(obj, function(v, index, list) {
|
|
1539
|
-
computed = iteratee(v, index, list);
|
|
1540
|
-
if (computed < lastComputed || (computed === Infinity && result === Infinity)) {
|
|
1541
|
-
result = v;
|
|
1542
|
-
lastComputed = computed;
|
|
1543
|
-
}
|
|
1544
|
-
});
|
|
1545
|
-
}
|
|
1546
|
-
return result;
|
|
1547
|
-
}
|
|
1548
|
-
|
|
1549
|
-
// Safely create a real, live array from anything iterable.
|
|
1550
|
-
var reStrSymbol = /[^\ud800-\udfff]|[\ud800-\udbff][\udc00-\udfff]|[\ud800-\udfff]/g;
|
|
1551
|
-
function toArray(obj) {
|
|
1552
|
-
if (!obj) return [];
|
|
1553
|
-
if (isArray(obj)) return slice.call(obj);
|
|
1554
|
-
if (isString(obj)) {
|
|
1555
|
-
// Keep surrogate pair characters together.
|
|
1556
|
-
return obj.match(reStrSymbol);
|
|
1557
|
-
}
|
|
1558
|
-
if (isArrayLike(obj)) return map(obj, identity);
|
|
1559
|
-
return values(obj);
|
|
1560
|
-
}
|
|
1561
|
-
|
|
1562
|
-
// Sample **n** random values from a collection using the modern version of the
|
|
1563
|
-
// [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher–Yates_shuffle).
|
|
1564
|
-
// If **n** is not specified, returns a single random element.
|
|
1565
|
-
// The internal `guard` argument allows it to work with `_.map`.
|
|
1566
|
-
function sample(obj, n, guard) {
|
|
1567
|
-
if (n == null || guard) {
|
|
1568
|
-
if (!isArrayLike(obj)) obj = values(obj);
|
|
1569
|
-
return obj[random$1(obj.length - 1)];
|
|
1570
|
-
}
|
|
1571
|
-
var sample = toArray(obj);
|
|
1572
|
-
var length = getLength(sample);
|
|
1573
|
-
n = Math.max(Math.min(n, length), 0);
|
|
1574
|
-
var last = length - 1;
|
|
1575
|
-
for (var index = 0; index < n; index++) {
|
|
1576
|
-
var rand = random$1(index, last);
|
|
1577
|
-
var temp = sample[index];
|
|
1578
|
-
sample[index] = sample[rand];
|
|
1579
|
-
sample[rand] = temp;
|
|
1580
|
-
}
|
|
1581
|
-
return sample.slice(0, n);
|
|
1582
|
-
}
|
|
1583
|
-
|
|
1584
|
-
// Shuffle a collection.
|
|
1585
|
-
function shuffle$1(obj) {
|
|
1586
|
-
return sample(obj, Infinity);
|
|
1587
|
-
}
|
|
1588
|
-
|
|
1589
|
-
// Sort the object's values by a criterion produced by an iteratee.
|
|
1590
|
-
function sortBy(obj, iteratee, context) {
|
|
1591
|
-
var index = 0;
|
|
1592
|
-
iteratee = cb(iteratee, context);
|
|
1593
|
-
return pluck$1(map(obj, function(value, key, list) {
|
|
1594
|
-
return {
|
|
1595
|
-
value: value,
|
|
1596
|
-
index: index++,
|
|
1597
|
-
criteria: iteratee(value, key, list)
|
|
1598
|
-
};
|
|
1599
|
-
}).sort(function(left, right) {
|
|
1600
|
-
var a = left.criteria;
|
|
1601
|
-
var b = right.criteria;
|
|
1602
|
-
if (a !== b) {
|
|
1603
|
-
if (a > b || a === void 0) return 1;
|
|
1604
|
-
if (a < b || b === void 0) return -1;
|
|
1605
|
-
}
|
|
1606
|
-
return left.index - right.index;
|
|
1607
|
-
}), 'value');
|
|
1608
|
-
}
|
|
1609
|
-
|
|
1610
|
-
// An internal function used for aggregate "group by" operations.
|
|
1611
|
-
function group(behavior, partition) {
|
|
1612
|
-
return function(obj, iteratee, context) {
|
|
1613
|
-
var result = partition ? [[], []] : {};
|
|
1614
|
-
iteratee = cb(iteratee, context);
|
|
1615
|
-
each(obj, function(value, index) {
|
|
1616
|
-
var key = iteratee(value, index, obj);
|
|
1617
|
-
behavior(result, value, key);
|
|
1618
|
-
});
|
|
1619
|
-
return result;
|
|
1620
|
-
};
|
|
1621
|
-
}
|
|
1622
|
-
|
|
1623
|
-
// Groups the object's values by a criterion. Pass either a string attribute
|
|
1624
|
-
// to group by, or a function that returns the criterion.
|
|
1625
|
-
var groupBy = group(function(result, value, key) {
|
|
1626
|
-
if (has$1(result, key)) result[key].push(value); else result[key] = [value];
|
|
1627
|
-
});
|
|
1628
|
-
|
|
1629
|
-
// Indexes the object's values by a criterion, similar to `_.groupBy`, but for
|
|
1630
|
-
// when you know that your index values will be unique.
|
|
1631
|
-
var indexBy = group(function(result, value, key) {
|
|
1632
|
-
result[key] = value;
|
|
1633
|
-
});
|
|
1634
|
-
|
|
1635
|
-
// Counts instances of an object that group by a certain criterion. Pass
|
|
1636
|
-
// either a string attribute to count by, or a function that returns the
|
|
1637
|
-
// criterion.
|
|
1638
|
-
var countBy = group(function(result, value, key) {
|
|
1639
|
-
if (has$1(result, key)) result[key]++; else result[key] = 1;
|
|
1640
|
-
});
|
|
1641
|
-
|
|
1642
|
-
// Split a collection into two arrays: one whose elements all pass the given
|
|
1643
|
-
// truth test, and one whose elements all do not pass the truth test.
|
|
1644
|
-
var partition = group(function(result, value, pass) {
|
|
1645
|
-
result[pass ? 0 : 1].push(value);
|
|
1646
|
-
}, true);
|
|
1647
|
-
|
|
1648
|
-
// Return the number of elements in a collection.
|
|
1649
|
-
function size(obj) {
|
|
1650
|
-
if (obj == null) return 0;
|
|
1651
|
-
return isArrayLike(obj) ? obj.length : keys(obj).length;
|
|
1652
|
-
}
|
|
1653
|
-
|
|
1654
|
-
// Internal `_.pick` helper function to determine whether `key` is an enumerable
|
|
1655
|
-
// property name of `obj`.
|
|
1656
|
-
function keyInObj(value, key, obj) {
|
|
1657
|
-
return key in obj;
|
|
1658
|
-
}
|
|
1659
|
-
|
|
1660
|
-
// Return a copy of the object only containing the allowed properties.
|
|
1661
|
-
var pick = restArguments(function(obj, keys) {
|
|
1662
|
-
var result = {}, iteratee = keys[0];
|
|
1663
|
-
if (obj == null) return result;
|
|
1664
|
-
if (isFunction$1(iteratee)) {
|
|
1665
|
-
if (keys.length > 1) iteratee = optimizeCb(iteratee, keys[1]);
|
|
1666
|
-
keys = allKeys(obj);
|
|
1667
|
-
} else {
|
|
1668
|
-
iteratee = keyInObj;
|
|
1669
|
-
keys = flatten$1(keys, false, false);
|
|
1670
|
-
obj = Object(obj);
|
|
1671
|
-
}
|
|
1672
|
-
for (var i = 0, length = keys.length; i < length; i++) {
|
|
1673
|
-
var key = keys[i];
|
|
1674
|
-
var value = obj[key];
|
|
1675
|
-
if (iteratee(value, key, obj)) result[key] = value;
|
|
1676
|
-
}
|
|
1677
|
-
return result;
|
|
1678
|
-
});
|
|
1679
|
-
|
|
1680
|
-
// Return a copy of the object without the disallowed properties.
|
|
1681
|
-
var omit = restArguments(function(obj, keys) {
|
|
1682
|
-
var iteratee = keys[0], context;
|
|
1683
|
-
if (isFunction$1(iteratee)) {
|
|
1684
|
-
iteratee = negate(iteratee);
|
|
1685
|
-
if (keys.length > 1) context = keys[1];
|
|
1686
|
-
} else {
|
|
1687
|
-
keys = map(flatten$1(keys, false, false), String);
|
|
1688
|
-
iteratee = function(value, key) {
|
|
1689
|
-
return !contains(keys, key);
|
|
1690
|
-
};
|
|
1691
|
-
}
|
|
1692
|
-
return pick(obj, iteratee, context);
|
|
1693
|
-
});
|
|
1694
|
-
|
|
1695
|
-
// Returns everything but the last entry of the array. Especially useful on
|
|
1696
|
-
// the arguments object. Passing **n** will return all the values in
|
|
1697
|
-
// the array, excluding the last N.
|
|
1698
|
-
function initial(array, n, guard) {
|
|
1699
|
-
return slice.call(array, 0, Math.max(0, array.length - (n == null || guard ? 1 : n)));
|
|
1700
|
-
}
|
|
1701
|
-
|
|
1702
|
-
// Get the first element of an array. Passing **n** will return the first N
|
|
1703
|
-
// values in the array. The **guard** check allows it to work with `_.map`.
|
|
1704
|
-
function first(array, n, guard) {
|
|
1705
|
-
if (array == null || array.length < 1) return n == null || guard ? void 0 : [];
|
|
1706
|
-
if (n == null || guard) return array[0];
|
|
1707
|
-
return initial(array, array.length - n);
|
|
1708
|
-
}
|
|
1709
|
-
|
|
1710
|
-
// Returns everything but the first entry of the `array`. Especially useful on
|
|
1711
|
-
// the `arguments` object. Passing an **n** will return the rest N values in the
|
|
1712
|
-
// `array`.
|
|
1713
|
-
function rest(array, n, guard) {
|
|
1714
|
-
return slice.call(array, n == null || guard ? 1 : n);
|
|
1715
|
-
}
|
|
1716
|
-
|
|
1717
|
-
// Get the last element of an array. Passing **n** will return the last N
|
|
1718
|
-
// values in the array.
|
|
1719
|
-
function last(array, n, guard) {
|
|
1720
|
-
if (array == null || array.length < 1) return n == null || guard ? void 0 : [];
|
|
1721
|
-
if (n == null || guard) return array[array.length - 1];
|
|
1722
|
-
return rest(array, Math.max(0, array.length - n));
|
|
1723
|
-
}
|
|
1724
|
-
|
|
1725
|
-
// Trim out all falsy values from an array.
|
|
1726
|
-
function compact(array) {
|
|
1727
|
-
return filter(array, Boolean);
|
|
1728
|
-
}
|
|
1729
|
-
|
|
1730
|
-
// Flatten out an array, either recursively (by default), or up to `depth`.
|
|
1731
|
-
// Passing `true` or `false` as `depth` means `1` or `Infinity`, respectively.
|
|
1732
|
-
function flatten(array, depth) {
|
|
1733
|
-
return flatten$1(array, depth, false);
|
|
1734
|
-
}
|
|
1735
|
-
|
|
1736
|
-
// Take the difference between one array and a number of other arrays.
|
|
1737
|
-
// Only the elements present in just the first array will remain.
|
|
1738
|
-
var difference = restArguments(function(array, rest) {
|
|
1739
|
-
rest = flatten$1(rest, true, true);
|
|
1740
|
-
return filter(array, function(value){
|
|
1741
|
-
return !contains(rest, value);
|
|
1742
|
-
});
|
|
1743
|
-
});
|
|
1744
|
-
|
|
1745
|
-
// Return a version of the array that does not contain the specified value(s).
|
|
1746
|
-
var without = restArguments(function(array, otherArrays) {
|
|
1747
|
-
return difference(array, otherArrays);
|
|
1748
|
-
});
|
|
1749
|
-
|
|
1750
|
-
// Produce a duplicate-free version of the array. If the array has already
|
|
1751
|
-
// been sorted, you have the option of using a faster algorithm.
|
|
1752
|
-
// The faster algorithm will not work with an iteratee if the iteratee
|
|
1753
|
-
// is not a one-to-one function, so providing an iteratee will disable
|
|
1754
|
-
// the faster algorithm.
|
|
1755
|
-
function uniq(array, isSorted, iteratee, context) {
|
|
1756
|
-
if (!isBoolean(isSorted)) {
|
|
1757
|
-
context = iteratee;
|
|
1758
|
-
iteratee = isSorted;
|
|
1759
|
-
isSorted = false;
|
|
1760
|
-
}
|
|
1761
|
-
if (iteratee != null) iteratee = cb(iteratee, context);
|
|
1762
|
-
var result = [];
|
|
1763
|
-
var seen = [];
|
|
1764
|
-
for (var i = 0, length = getLength(array); i < length; i++) {
|
|
1765
|
-
var value = array[i],
|
|
1766
|
-
computed = iteratee ? iteratee(value, i, array) : value;
|
|
1767
|
-
if (isSorted && !iteratee) {
|
|
1768
|
-
if (!i || seen !== computed) result.push(value);
|
|
1769
|
-
seen = computed;
|
|
1770
|
-
} else if (iteratee) {
|
|
1771
|
-
if (!contains(seen, computed)) {
|
|
1772
|
-
seen.push(computed);
|
|
1773
|
-
result.push(value);
|
|
1774
|
-
}
|
|
1775
|
-
} else if (!contains(result, value)) {
|
|
1776
|
-
result.push(value);
|
|
1777
|
-
}
|
|
1778
|
-
}
|
|
1779
|
-
return result;
|
|
1780
|
-
}
|
|
1781
|
-
|
|
1782
|
-
// Produce an array that contains the union: each distinct element from all of
|
|
1783
|
-
// the passed-in arrays.
|
|
1784
|
-
var union$1 = restArguments(function(arrays) {
|
|
1785
|
-
return uniq(flatten$1(arrays, true, true));
|
|
1786
|
-
});
|
|
1787
|
-
|
|
1788
|
-
// Produce an array that contains every item shared between all the
|
|
1789
|
-
// passed-in arrays.
|
|
1790
|
-
function intersection(array) {
|
|
1791
|
-
var result = [];
|
|
1792
|
-
var argsLength = arguments.length;
|
|
1793
|
-
for (var i = 0, length = getLength(array); i < length; i++) {
|
|
1794
|
-
var item = array[i];
|
|
1795
|
-
if (contains(result, item)) continue;
|
|
1796
|
-
var j;
|
|
1797
|
-
for (j = 1; j < argsLength; j++) {
|
|
1798
|
-
if (!contains(arguments[j], item)) break;
|
|
1799
|
-
}
|
|
1800
|
-
if (j === argsLength) result.push(item);
|
|
1801
|
-
}
|
|
1802
|
-
return result;
|
|
1803
|
-
}
|
|
1804
|
-
|
|
1805
|
-
// Complement of zip. Unzip accepts an array of arrays and groups
|
|
1806
|
-
// each array's elements on shared indices.
|
|
1807
|
-
function unzip(array) {
|
|
1808
|
-
var length = (array && max(array, getLength).length) || 0;
|
|
1809
|
-
var result = Array(length);
|
|
1810
|
-
|
|
1811
|
-
for (var index = 0; index < length; index++) {
|
|
1812
|
-
result[index] = pluck$1(array, index);
|
|
1813
|
-
}
|
|
1814
|
-
return result;
|
|
1815
|
-
}
|
|
1816
|
-
|
|
1817
|
-
// Zip together multiple lists into a single array -- elements that share
|
|
1818
|
-
// an index go together.
|
|
1819
|
-
var zip = restArguments(unzip);
|
|
1820
|
-
|
|
1821
|
-
// Converts lists into objects. Pass either a single array of `[key, value]`
|
|
1822
|
-
// pairs, or two parallel arrays of the same length -- one of keys, and one of
|
|
1823
|
-
// the corresponding values. Passing by pairs is the reverse of `_.pairs`.
|
|
1824
|
-
function object$1(list, values) {
|
|
1825
|
-
var result = {};
|
|
1826
|
-
for (var i = 0, length = getLength(list); i < length; i++) {
|
|
1827
|
-
if (values) {
|
|
1828
|
-
result[list[i]] = values[i];
|
|
1829
|
-
} else {
|
|
1830
|
-
result[list[i][0]] = list[i][1];
|
|
9
|
+
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
10
|
+
|
|
11
|
+
function _interopNamespace(e) {
|
|
12
|
+
if (e && e.__esModule) return e;
|
|
13
|
+
var n = Object.create(null);
|
|
14
|
+
if (e) {
|
|
15
|
+
Object.keys(e).forEach(function (k) {
|
|
16
|
+
if (k !== 'default') {
|
|
17
|
+
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
18
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
19
|
+
enumerable: true,
|
|
20
|
+
get: function () { return e[k]; }
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
});
|
|
1831
24
|
}
|
|
1832
|
-
|
|
1833
|
-
|
|
25
|
+
n["default"] = e;
|
|
26
|
+
return Object.freeze(n);
|
|
1834
27
|
}
|
|
1835
28
|
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
// [the Python documentation](https://docs.python.org/library/functions.html#range).
|
|
1839
|
-
function range(start, stop, step) {
|
|
1840
|
-
if (stop == null) {
|
|
1841
|
-
stop = start || 0;
|
|
1842
|
-
start = 0;
|
|
1843
|
-
}
|
|
1844
|
-
if (!step) {
|
|
1845
|
-
step = stop < start ? -1 : 1;
|
|
1846
|
-
}
|
|
1847
|
-
|
|
1848
|
-
var length = Math.max(Math.ceil((stop - start) / step), 0);
|
|
1849
|
-
var range = Array(length);
|
|
1850
|
-
|
|
1851
|
-
for (var idx = 0; idx < length; idx++, start += step) {
|
|
1852
|
-
range[idx] = start;
|
|
1853
|
-
}
|
|
1854
|
-
|
|
1855
|
-
return range;
|
|
1856
|
-
}
|
|
1857
|
-
|
|
1858
|
-
// Chunk a single array into multiple arrays, each containing `count` or fewer
|
|
1859
|
-
// items.
|
|
1860
|
-
function chunk(array, count) {
|
|
1861
|
-
if (count == null || count < 1) return [];
|
|
1862
|
-
var result = [];
|
|
1863
|
-
var i = 0, length = array.length;
|
|
1864
|
-
while (i < length) {
|
|
1865
|
-
result.push(slice.call(array, i, i += count));
|
|
1866
|
-
}
|
|
1867
|
-
return result;
|
|
1868
|
-
}
|
|
1869
|
-
|
|
1870
|
-
// Helper function to continue chaining intermediate results.
|
|
1871
|
-
function chainResult(instance, obj) {
|
|
1872
|
-
return instance._chain ? _$1(obj).chain() : obj;
|
|
1873
|
-
}
|
|
1874
|
-
|
|
1875
|
-
// Add your own custom functions to the Underscore object.
|
|
1876
|
-
function mixin(obj) {
|
|
1877
|
-
each(functions(obj), function(name) {
|
|
1878
|
-
var func = _$1[name] = obj[name];
|
|
1879
|
-
_$1.prototype[name] = function() {
|
|
1880
|
-
var args = [this._wrapped];
|
|
1881
|
-
push.apply(args, arguments);
|
|
1882
|
-
return chainResult(this, func.apply(_$1, args));
|
|
1883
|
-
};
|
|
1884
|
-
});
|
|
1885
|
-
return _$1;
|
|
1886
|
-
}
|
|
1887
|
-
|
|
1888
|
-
// Add all mutator `Array` functions to the wrapper.
|
|
1889
|
-
each(['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'], function(name) {
|
|
1890
|
-
var method = ArrayProto[name];
|
|
1891
|
-
_$1.prototype[name] = function() {
|
|
1892
|
-
var obj = this._wrapped;
|
|
1893
|
-
if (obj != null) {
|
|
1894
|
-
method.apply(obj, arguments);
|
|
1895
|
-
if ((name === 'shift' || name === 'splice') && obj.length === 0) {
|
|
1896
|
-
delete obj[0];
|
|
1897
|
-
}
|
|
1898
|
-
}
|
|
1899
|
-
return chainResult(this, obj);
|
|
1900
|
-
};
|
|
1901
|
-
});
|
|
1902
|
-
|
|
1903
|
-
// Add all accessor `Array` functions to the wrapper.
|
|
1904
|
-
each(['concat', 'join', 'slice'], function(name) {
|
|
1905
|
-
var method = ArrayProto[name];
|
|
1906
|
-
_$1.prototype[name] = function() {
|
|
1907
|
-
var obj = this._wrapped;
|
|
1908
|
-
if (obj != null) obj = method.apply(obj, arguments);
|
|
1909
|
-
return chainResult(this, obj);
|
|
1910
|
-
};
|
|
1911
|
-
});
|
|
1912
|
-
|
|
1913
|
-
// Named Exports
|
|
1914
|
-
|
|
1915
|
-
var allExports = /*#__PURE__*/Object.freeze({
|
|
1916
|
-
__proto__: null,
|
|
1917
|
-
VERSION: VERSION,
|
|
1918
|
-
restArguments: restArguments,
|
|
1919
|
-
isObject: isObject$1,
|
|
1920
|
-
isNull: isNull,
|
|
1921
|
-
isUndefined: isUndefined,
|
|
1922
|
-
isBoolean: isBoolean,
|
|
1923
|
-
isElement: isElement,
|
|
1924
|
-
isString: isString,
|
|
1925
|
-
isNumber: isNumber,
|
|
1926
|
-
isDate: isDate,
|
|
1927
|
-
isRegExp: isRegExp,
|
|
1928
|
-
isError: isError,
|
|
1929
|
-
isSymbol: isSymbol,
|
|
1930
|
-
isArrayBuffer: isArrayBuffer,
|
|
1931
|
-
isDataView: isDataView$1,
|
|
1932
|
-
isArray: isArray,
|
|
1933
|
-
isFunction: isFunction$1,
|
|
1934
|
-
isArguments: isArguments$1,
|
|
1935
|
-
isFinite: isFinite$1,
|
|
1936
|
-
isNaN: isNaN$1,
|
|
1937
|
-
isTypedArray: isTypedArray$1,
|
|
1938
|
-
isEmpty: isEmpty,
|
|
1939
|
-
isMatch: isMatch,
|
|
1940
|
-
isEqual: isEqual,
|
|
1941
|
-
isMap: isMap,
|
|
1942
|
-
isWeakMap: isWeakMap,
|
|
1943
|
-
isSet: isSet,
|
|
1944
|
-
isWeakSet: isWeakSet,
|
|
1945
|
-
keys: keys,
|
|
1946
|
-
allKeys: allKeys,
|
|
1947
|
-
values: values,
|
|
1948
|
-
pairs: pairs,
|
|
1949
|
-
invert: invert,
|
|
1950
|
-
functions: functions,
|
|
1951
|
-
methods: functions,
|
|
1952
|
-
extend: extend,
|
|
1953
|
-
extendOwn: extendOwn,
|
|
1954
|
-
assign: extendOwn,
|
|
1955
|
-
defaults: defaults,
|
|
1956
|
-
create: create,
|
|
1957
|
-
clone: clone,
|
|
1958
|
-
tap: tap,
|
|
1959
|
-
get: get,
|
|
1960
|
-
has: has,
|
|
1961
|
-
mapObject: mapObject$1,
|
|
1962
|
-
identity: identity,
|
|
1963
|
-
constant: constant$1,
|
|
1964
|
-
noop: noop,
|
|
1965
|
-
toPath: toPath$1,
|
|
1966
|
-
property: property,
|
|
1967
|
-
propertyOf: propertyOf,
|
|
1968
|
-
matcher: matcher,
|
|
1969
|
-
matches: matcher,
|
|
1970
|
-
times: times,
|
|
1971
|
-
random: random$1,
|
|
1972
|
-
now: now,
|
|
1973
|
-
escape: escape,
|
|
1974
|
-
unescape: unescape,
|
|
1975
|
-
templateSettings: templateSettings,
|
|
1976
|
-
template: template,
|
|
1977
|
-
result: result,
|
|
1978
|
-
uniqueId: uniqueId,
|
|
1979
|
-
chain: chain,
|
|
1980
|
-
iteratee: iteratee,
|
|
1981
|
-
partial: partial,
|
|
1982
|
-
bind: bind,
|
|
1983
|
-
bindAll: bindAll,
|
|
1984
|
-
memoize: memoize,
|
|
1985
|
-
delay: delay,
|
|
1986
|
-
defer: defer,
|
|
1987
|
-
throttle: throttle,
|
|
1988
|
-
debounce: debounce,
|
|
1989
|
-
wrap: wrap,
|
|
1990
|
-
negate: negate,
|
|
1991
|
-
compose: compose,
|
|
1992
|
-
after: after,
|
|
1993
|
-
before: before,
|
|
1994
|
-
once: once,
|
|
1995
|
-
findKey: findKey,
|
|
1996
|
-
findIndex: findIndex,
|
|
1997
|
-
findLastIndex: findLastIndex,
|
|
1998
|
-
sortedIndex: sortedIndex,
|
|
1999
|
-
indexOf: indexOf,
|
|
2000
|
-
lastIndexOf: lastIndexOf,
|
|
2001
|
-
find: find,
|
|
2002
|
-
detect: find,
|
|
2003
|
-
findWhere: findWhere,
|
|
2004
|
-
each: each,
|
|
2005
|
-
forEach: each,
|
|
2006
|
-
map: map,
|
|
2007
|
-
collect: map,
|
|
2008
|
-
reduce: reduce,
|
|
2009
|
-
foldl: reduce,
|
|
2010
|
-
inject: reduce,
|
|
2011
|
-
reduceRight: reduceRight,
|
|
2012
|
-
foldr: reduceRight,
|
|
2013
|
-
filter: filter,
|
|
2014
|
-
select: filter,
|
|
2015
|
-
reject: reject,
|
|
2016
|
-
every: every,
|
|
2017
|
-
all: every,
|
|
2018
|
-
some: some,
|
|
2019
|
-
any: some,
|
|
2020
|
-
contains: contains,
|
|
2021
|
-
includes: contains,
|
|
2022
|
-
include: contains,
|
|
2023
|
-
invoke: invoke,
|
|
2024
|
-
pluck: pluck$1,
|
|
2025
|
-
where: where,
|
|
2026
|
-
max: max,
|
|
2027
|
-
min: min,
|
|
2028
|
-
shuffle: shuffle$1,
|
|
2029
|
-
sample: sample,
|
|
2030
|
-
sortBy: sortBy,
|
|
2031
|
-
groupBy: groupBy,
|
|
2032
|
-
indexBy: indexBy,
|
|
2033
|
-
countBy: countBy,
|
|
2034
|
-
partition: partition,
|
|
2035
|
-
toArray: toArray,
|
|
2036
|
-
size: size,
|
|
2037
|
-
pick: pick,
|
|
2038
|
-
omit: omit,
|
|
2039
|
-
first: first,
|
|
2040
|
-
head: first,
|
|
2041
|
-
take: first,
|
|
2042
|
-
initial: initial,
|
|
2043
|
-
last: last,
|
|
2044
|
-
rest: rest,
|
|
2045
|
-
tail: rest,
|
|
2046
|
-
drop: rest,
|
|
2047
|
-
compact: compact,
|
|
2048
|
-
flatten: flatten,
|
|
2049
|
-
without: without,
|
|
2050
|
-
uniq: uniq,
|
|
2051
|
-
unique: uniq,
|
|
2052
|
-
union: union$1,
|
|
2053
|
-
intersection: intersection,
|
|
2054
|
-
difference: difference,
|
|
2055
|
-
unzip: unzip,
|
|
2056
|
-
transpose: unzip,
|
|
2057
|
-
zip: zip,
|
|
2058
|
-
object: object$1,
|
|
2059
|
-
range: range,
|
|
2060
|
-
chunk: chunk,
|
|
2061
|
-
mixin: mixin,
|
|
2062
|
-
'default': _$1
|
|
2063
|
-
});
|
|
2064
|
-
|
|
2065
|
-
// Default Export
|
|
2066
|
-
|
|
2067
|
-
// Add all of the Underscore functions to the wrapper object.
|
|
2068
|
-
var _ = mixin(allExports);
|
|
2069
|
-
// Legacy Node.js API.
|
|
2070
|
-
_._ = _;
|
|
29
|
+
var ___default = /*#__PURE__*/_interopDefaultLegacy(_);
|
|
30
|
+
var KAS__namespace = /*#__PURE__*/_interopNamespace(KAS);
|
|
2071
31
|
|
|
2072
32
|
function getMatrixSize(matrix) {
|
|
2073
33
|
const matrixSize = [1, 1];
|
|
2074
34
|
|
|
2075
35
|
// We need to find the widest row and tallest column to get the correct
|
|
2076
36
|
// matrix size.
|
|
2077
|
-
|
|
37
|
+
___default["default"](matrix).each((matrixRow, row) => {
|
|
2078
38
|
let rowWidth = 0;
|
|
2079
|
-
|
|
39
|
+
___default["default"](matrixRow).each((matrixCol, col) => {
|
|
2080
40
|
if (matrixCol != null && matrixCol.toString().length) {
|
|
2081
41
|
rowWidth = col + 1;
|
|
2082
42
|
}
|
|
@@ -2113,7 +73,9 @@ const getDecimalSeparator = locale => {
|
|
|
2113
73
|
const match = new Intl.NumberFormat(locale).format(numberWithDecimalSeparator)
|
|
2114
74
|
// 0x661 is ARABIC-INDIC DIGIT ONE
|
|
2115
75
|
// 0x6F1 is EXTENDED ARABIC-INDIC DIGIT ONE
|
|
2116
|
-
|
|
76
|
+
// 0x967 is DEVANAGARI DIGIT ONE
|
|
77
|
+
// 0x9e7 is BENGALI/BANGLA DIGIT ONE
|
|
78
|
+
.match(/[^\d\u0661\u06F1\u0967\u09e7]/);
|
|
2117
79
|
return match?.[0] ?? ".";
|
|
2118
80
|
}
|
|
2119
81
|
};
|
|
@@ -2154,10 +116,10 @@ function approximateDeepEqual(x, y) {
|
|
|
2154
116
|
return false;
|
|
2155
117
|
}
|
|
2156
118
|
if (typeof x === "object" && typeof y === "object" && !!x && !!y) {
|
|
2157
|
-
return x === y ||
|
|
119
|
+
return x === y || ___default["default"].all(x, function (v, k) {
|
|
2158
120
|
// @ts-expect-error - TS2536 - Type 'CollectionKey<T>' cannot be used to index type 'T'.
|
|
2159
121
|
return approximateDeepEqual(y[k], v);
|
|
2160
|
-
}) &&
|
|
122
|
+
}) && ___default["default"].all(y, function (v, k) {
|
|
2161
123
|
// @ts-expect-error - TS2536 - Type 'CollectionKey<T>' cannot be used to index type 'T'.
|
|
2162
124
|
return approximateDeepEqual(x[k], v);
|
|
2163
125
|
});
|
|
@@ -2322,11 +284,11 @@ const PlotDefaults = {
|
|
|
2322
284
|
getPropsForCoeffs: function (coeffs) {
|
|
2323
285
|
return {
|
|
2324
286
|
// @ts-expect-error - TS2339 - Property 'getFunctionForCoeffs' does not exist on type '{ readonly areEqual: (coeffs1: any, coeffs2: any) => boolean; readonly Movable: any; readonly getPropsForCoeffs: (coeffs: any) => any; }'.
|
|
2325
|
-
fn:
|
|
287
|
+
fn: ___default["default"].partial(this.getFunctionForCoeffs, coeffs)
|
|
2326
288
|
};
|
|
2327
289
|
}
|
|
2328
290
|
};
|
|
2329
|
-
const Linear =
|
|
291
|
+
const Linear = ___default["default"].extend({}, PlotDefaults, {
|
|
2330
292
|
url: "https://ka-perseus-graphie.s3.amazonaws.com/67aaf581e6d9ef9038c10558a1f70ac21c11c9f8.png",
|
|
2331
293
|
defaultCoords: [[0.25, 0.75], [0.75, 0.75]],
|
|
2332
294
|
getCoefficients: function (coords) {
|
|
@@ -2353,7 +315,7 @@ const Linear = _.extend({}, PlotDefaults, {
|
|
|
2353
315
|
return "y = " + m.toFixed(3) + "x + " + b.toFixed(3);
|
|
2354
316
|
}
|
|
2355
317
|
});
|
|
2356
|
-
const Quadratic =
|
|
318
|
+
const Quadratic = ___default["default"].extend({}, PlotDefaults, {
|
|
2357
319
|
url: "https://ka-perseus-graphie.s3.amazonaws.com/e23d36e6fc29ee37174e92c9daba2a66677128ab.png",
|
|
2358
320
|
defaultCoords: [[0.5, 0.5], [0.75, 0.75]],
|
|
2359
321
|
movable: MOVABLES.PARABOLA,
|
|
@@ -2392,7 +354,7 @@ const Quadratic = _.extend({}, PlotDefaults, {
|
|
|
2392
354
|
return "y = " + a.toFixed(3) + "x^2 + " + b.toFixed(3) + "x + " + c.toFixed(3);
|
|
2393
355
|
}
|
|
2394
356
|
});
|
|
2395
|
-
const Sinusoid =
|
|
357
|
+
const Sinusoid = ___default["default"].extend({}, PlotDefaults, {
|
|
2396
358
|
url: "https://ka-perseus-graphie.s3.amazonaws.com/3d68e7718498475f53b206c2ab285626baf8857e.png",
|
|
2397
359
|
defaultCoords: [[0.5, 0.5], [0.6, 0.6]],
|
|
2398
360
|
movable: MOVABLES.SINUSOID,
|
|
@@ -2432,7 +394,7 @@ const Sinusoid = _.extend({}, PlotDefaults, {
|
|
|
2432
394
|
return approximateDeepEqual(canonicalSineCoefficients(coeffs1), canonicalSineCoefficients(coeffs2));
|
|
2433
395
|
}
|
|
2434
396
|
});
|
|
2435
|
-
const Tangent =
|
|
397
|
+
const Tangent = ___default["default"].extend({}, PlotDefaults, {
|
|
2436
398
|
url: "https://ka-perseus-graphie.s3.amazonaws.com/7db80d23c35214f98659fe1cf0765811c1bbfbba.png",
|
|
2437
399
|
defaultCoords: [[0.5, 0.5], [0.75, 0.75]],
|
|
2438
400
|
getCoefficients: function (coords) {
|
|
@@ -2463,7 +425,7 @@ const Tangent = _.extend({}, PlotDefaults, {
|
|
|
2463
425
|
return approximateDeepEqual(canonicalTangentCoefficients(coeffs1), canonicalTangentCoefficients(coeffs2));
|
|
2464
426
|
}
|
|
2465
427
|
});
|
|
2466
|
-
const Exponential =
|
|
428
|
+
const Exponential = ___default["default"].extend({}, PlotDefaults, {
|
|
2467
429
|
url: "https://ka-perseus-graphie.s3.amazonaws.com/9cbfad55525e3ce755a31a631b074670a5dad611.png",
|
|
2468
430
|
defaultCoords: [[0.5, 0.55], [0.75, 0.75]],
|
|
2469
431
|
defaultAsymptote: [[0, 0.5], [1.0, 0.5]],
|
|
@@ -2486,23 +448,23 @@ const Exponential = _.extend({}, PlotDefaults, {
|
|
|
2486
448
|
*/
|
|
2487
449
|
extraCoordConstraint: function (newCoord, oldCoord, coords, asymptote, graph) {
|
|
2488
450
|
const y = asymptote[0][1];
|
|
2489
|
-
return
|
|
451
|
+
return ___default["default"].all(coords, coord => coord[1] !== y);
|
|
2490
452
|
},
|
|
2491
453
|
extraAsymptoteConstraint: function (newCoord, oldCoord, coords, asymptote, graph) {
|
|
2492
454
|
const y = newCoord[1];
|
|
2493
|
-
const isValid =
|
|
455
|
+
const isValid = ___default["default"].all(coords, coord => coord[1] > y) || ___default["default"].all(coords, coord => coord[1] < y);
|
|
2494
456
|
if (isValid) {
|
|
2495
457
|
return [oldCoord[0], y];
|
|
2496
458
|
}
|
|
2497
459
|
// Snap the asymptote as close as possible, i.e., if the user moves
|
|
2498
460
|
// the mouse really quickly into an invalid region
|
|
2499
461
|
const oldY = oldCoord[1];
|
|
2500
|
-
const wasBelow =
|
|
462
|
+
const wasBelow = ___default["default"].all(coords, coord => coord[1] > oldY);
|
|
2501
463
|
if (wasBelow) {
|
|
2502
|
-
const bottomMost =
|
|
464
|
+
const bottomMost = ___default["default"].min(___default["default"].map(coords, coord => coord[1]));
|
|
2503
465
|
return [oldCoord[0], bottomMost - graph.snapStep[1]];
|
|
2504
466
|
}
|
|
2505
|
-
const topMost =
|
|
467
|
+
const topMost = ___default["default"].max(___default["default"].map(coords, coord => coord[1]));
|
|
2506
468
|
return [oldCoord[0], topMost + graph.snapStep[1]];
|
|
2507
469
|
},
|
|
2508
470
|
allowReflectOverAsymptote: true,
|
|
@@ -2531,29 +493,29 @@ const Exponential = _.extend({}, PlotDefaults, {
|
|
|
2531
493
|
return "y = " + a.toFixed(3) + "e^(" + b.toFixed(3) + "x) + " + c.toFixed(3);
|
|
2532
494
|
}
|
|
2533
495
|
});
|
|
2534
|
-
const Logarithm =
|
|
496
|
+
const Logarithm = ___default["default"].extend({}, PlotDefaults, {
|
|
2535
497
|
url: "https://ka-perseus-graphie.s3.amazonaws.com/f6491e99d34af34d924bfe0231728ad912068dc3.png",
|
|
2536
498
|
defaultCoords: [[0.55, 0.5], [0.75, 0.75]],
|
|
2537
499
|
defaultAsymptote: [[0.5, 0], [0.5, 1.0]],
|
|
2538
500
|
extraCoordConstraint: function (newCoord, oldCoord, coords, asymptote, graph) {
|
|
2539
501
|
const x = asymptote[0][0];
|
|
2540
|
-
return
|
|
502
|
+
return ___default["default"].all(coords, coord => coord[0] !== x) && coords[0][1] !== coords[1][1];
|
|
2541
503
|
},
|
|
2542
504
|
extraAsymptoteConstraint: function (newCoord, oldCoord, coords, asymptote, graph) {
|
|
2543
505
|
const x = newCoord[0];
|
|
2544
|
-
const isValid =
|
|
506
|
+
const isValid = ___default["default"].all(coords, coord => coord[0] > x) || ___default["default"].all(coords, coord => coord[0] < x);
|
|
2545
507
|
if (isValid) {
|
|
2546
508
|
return [x, oldCoord[1]];
|
|
2547
509
|
}
|
|
2548
510
|
// Snap the asymptote as close as possible, i.e., if the user moves
|
|
2549
511
|
// the mouse really quickly into an invalid region
|
|
2550
512
|
const oldX = oldCoord[0];
|
|
2551
|
-
const wasLeft =
|
|
513
|
+
const wasLeft = ___default["default"].all(coords, coord => coord[0] > oldX);
|
|
2552
514
|
if (wasLeft) {
|
|
2553
|
-
const leftMost =
|
|
515
|
+
const leftMost = ___default["default"].min(___default["default"].map(coords, coord => coord[0]));
|
|
2554
516
|
return [leftMost - graph.snapStep[0], oldCoord[1]];
|
|
2555
517
|
}
|
|
2556
|
-
const rightMost =
|
|
518
|
+
const rightMost = ___default["default"].max(___default["default"].map(coords, coord => coord[0]));
|
|
2557
519
|
return [rightMost + graph.snapStep[0], oldCoord[1]];
|
|
2558
520
|
},
|
|
2559
521
|
allowReflectOverAsymptote: true,
|
|
@@ -2563,7 +525,7 @@ const Logarithm = _.extend({}, PlotDefaults, {
|
|
|
2563
525
|
// perform some algebra on the coefficients. This also unifies the
|
|
2564
526
|
// logic between the two 'models'.
|
|
2565
527
|
const flip = coord => [coord[1], coord[0]];
|
|
2566
|
-
const inverseCoeffs = Exponential.getCoefficients(
|
|
528
|
+
const inverseCoeffs = Exponential.getCoefficients(___default["default"].map(coords, flip), ___default["default"].map(asymptote, flip));
|
|
2567
529
|
if (inverseCoeffs) {
|
|
2568
530
|
const c = -inverseCoeffs[2] / inverseCoeffs[0];
|
|
2569
531
|
const b = 1 / inverseCoeffs[0];
|
|
@@ -2588,7 +550,7 @@ const Logarithm = _.extend({}, PlotDefaults, {
|
|
|
2588
550
|
return "y = ln(" + a.toFixed(3) + "x + " + b.toFixed(3) + ") + " + c.toFixed(3);
|
|
2589
551
|
}
|
|
2590
552
|
});
|
|
2591
|
-
const AbsoluteValue =
|
|
553
|
+
const AbsoluteValue = ___default["default"].extend({}, PlotDefaults, {
|
|
2592
554
|
url: "https://ka-perseus-graphie.s3.amazonaws.com/8256a630175a0cb1d11de223d6de0266daf98721.png",
|
|
2593
555
|
defaultCoords: [[0.5, 0.5], [0.75, 0.75]],
|
|
2594
556
|
getCoefficients: function (coords) {
|
|
@@ -2632,7 +594,7 @@ const functionTypeMapping = {
|
|
|
2632
594
|
logarithm: Logarithm,
|
|
2633
595
|
absolute_value: AbsoluteValue
|
|
2634
596
|
};
|
|
2635
|
-
const allTypes =
|
|
597
|
+
const allTypes = ___default["default"].keys(functionTypeMapping);
|
|
2636
598
|
function functionForType(type) {
|
|
2637
599
|
// @ts-expect-error: TypeScript doesn't know how to use deal with generics
|
|
2638
600
|
// and conditional types in this way.
|
|
@@ -3151,6 +1113,76 @@ const parseExplanationWidget = parseWidget(constant("explanation"), object({
|
|
|
3151
1113
|
static: defaulted(boolean, () => false)
|
|
3152
1114
|
}));
|
|
3153
1115
|
|
|
1116
|
+
const KeypadKeys = ["PLUS", "MINUS", "NEGATIVE", "TIMES", "DIVIDE", "DECIMAL", "PERIOD", "PERCENT", "CDOT", "EQUAL", "NEQ", "GT", "LT", "GEQ", "LEQ",
|
|
1117
|
+
// mobile native only
|
|
1118
|
+
"FRAC_INCLUSIVE",
|
|
1119
|
+
// mobile native only
|
|
1120
|
+
"FRAC_EXCLUSIVE",
|
|
1121
|
+
// mobile native only
|
|
1122
|
+
"FRAC", "EXP", "EXP_2", "EXP_3", "SQRT", "CUBE_ROOT", "RADICAL", "LEFT_PAREN", "RIGHT_PAREN", "LN", "LOG", "LOG_N", "SIN", "COS",
|
|
1123
|
+
// TODO(charlie): Add in additional Greek letters.,
|
|
1124
|
+
"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",
|
|
1125
|
+
// Multi-functional keys.
|
|
1126
|
+
"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"];
|
|
1127
|
+
|
|
1128
|
+
// Used by KeypadContext to pass around a renderer reference
|
|
1129
|
+
|
|
1130
|
+
/**
|
|
1131
|
+
* Scrape the answer forms for any variables or contants (like Pi)
|
|
1132
|
+
* that need to be included as keys on the keypad.
|
|
1133
|
+
*/
|
|
1134
|
+
function deriveExtraKeys(widgetOptions) {
|
|
1135
|
+
if (widgetOptions.extraKeys) {
|
|
1136
|
+
return widgetOptions.extraKeys;
|
|
1137
|
+
}
|
|
1138
|
+
|
|
1139
|
+
// If there are no extra symbols available, we include Pi anyway, so
|
|
1140
|
+
// that the "extra symbols" button doesn't appear empty.
|
|
1141
|
+
const defaultKeys = ["PI"];
|
|
1142
|
+
if (widgetOptions.answerForms == null) {
|
|
1143
|
+
return defaultKeys;
|
|
1144
|
+
}
|
|
1145
|
+
|
|
1146
|
+
// Extract any and all variables and constants from the answer forms.
|
|
1147
|
+
const uniqueExtraVariables = {};
|
|
1148
|
+
const uniqueExtraConstants = {};
|
|
1149
|
+
for (const answerForm of widgetOptions.answerForms) {
|
|
1150
|
+
const maybeExpr = KAS__namespace.parse(answerForm.value, widgetOptions);
|
|
1151
|
+
if (maybeExpr.parsed) {
|
|
1152
|
+
const expr = maybeExpr.expr;
|
|
1153
|
+
|
|
1154
|
+
// The keypad expects Greek letters to be capitalized (e.g., it
|
|
1155
|
+
// requires `PI` instead of `pi`). Right now, it only supports Pi
|
|
1156
|
+
// and Theta, so we special-case.
|
|
1157
|
+
const isGreek = symbol => symbol === "pi" || symbol === "theta";
|
|
1158
|
+
const toKey = symbol => isGreek(symbol) ? symbol.toUpperCase() : symbol;
|
|
1159
|
+
const isKey = key => KeypadKeys.includes(key);
|
|
1160
|
+
for (const variable of expr.getVars()) {
|
|
1161
|
+
const maybeKey = toKey(variable);
|
|
1162
|
+
if (isKey(maybeKey)) {
|
|
1163
|
+
uniqueExtraVariables[maybeKey] = true;
|
|
1164
|
+
}
|
|
1165
|
+
}
|
|
1166
|
+
for (const constant of expr.getConsts()) {
|
|
1167
|
+
const maybeKey = toKey(constant);
|
|
1168
|
+
if (isKey(maybeKey)) {
|
|
1169
|
+
uniqueExtraConstants[maybeKey] = true;
|
|
1170
|
+
}
|
|
1171
|
+
}
|
|
1172
|
+
}
|
|
1173
|
+
}
|
|
1174
|
+
|
|
1175
|
+
// TODO(charlie): Alert the keypad as to which of these symbols should be
|
|
1176
|
+
// treated as functions.
|
|
1177
|
+
const extraVariables = Object.keys(uniqueExtraVariables).sort();
|
|
1178
|
+
const extraConstants = Object.keys(uniqueExtraConstants).sort();
|
|
1179
|
+
const extraKeys = [...extraVariables, ...extraConstants];
|
|
1180
|
+
if (!extraKeys.length) {
|
|
1181
|
+
return defaultKeys;
|
|
1182
|
+
}
|
|
1183
|
+
return extraKeys;
|
|
1184
|
+
}
|
|
1185
|
+
|
|
3154
1186
|
// Given a function, creates a PartialParser that converts one type to another
|
|
3155
1187
|
// using that function. The returned parser never fails.
|
|
3156
1188
|
function convert(f) {
|
|
@@ -3253,11 +1285,25 @@ function removeInvalidAnswerForms(possiblyInvalid) {
|
|
|
3253
1285
|
}
|
|
3254
1286
|
return valid;
|
|
3255
1287
|
}
|
|
3256
|
-
const
|
|
1288
|
+
const version2$1 = object({
|
|
1289
|
+
major: constant(2),
|
|
1290
|
+
minor: number
|
|
1291
|
+
});
|
|
1292
|
+
const parseExpressionWidgetV2 = parseWidgetWithVersion(version2$1, constant("expression"), object({
|
|
1293
|
+
answerForms: pipeParsers(array(parsePossiblyInvalidAnswerForm)).then(convert(removeInvalidAnswerForms)).parser,
|
|
1294
|
+
functions: array(string),
|
|
1295
|
+
times: boolean,
|
|
1296
|
+
visibleLabel: optional(string),
|
|
1297
|
+
ariaLabel: optional(string),
|
|
1298
|
+
buttonSets: parseLegacyButtonSets,
|
|
1299
|
+
buttonsVisible: optional(enumeration("always", "never", "focused")),
|
|
1300
|
+
extraKeys: array(enumeration(...KeypadKeys))
|
|
1301
|
+
}));
|
|
1302
|
+
const version1$1 = object({
|
|
3257
1303
|
major: constant(1),
|
|
3258
1304
|
minor: number
|
|
3259
1305
|
});
|
|
3260
|
-
const parseExpressionWidgetV1 = parseWidgetWithVersion(version1, constant("expression"), object({
|
|
1306
|
+
const parseExpressionWidgetV1 = parseWidgetWithVersion(version1$1, constant("expression"), object({
|
|
3261
1307
|
answerForms: pipeParsers(array(parsePossiblyInvalidAnswerForm)).then(convert(removeInvalidAnswerForms)).parser,
|
|
3262
1308
|
functions: array(string),
|
|
3263
1309
|
times: boolean,
|
|
@@ -3266,11 +1312,33 @@ const parseExpressionWidgetV1 = parseWidgetWithVersion(version1, constant("expre
|
|
|
3266
1312
|
buttonSets: parseLegacyButtonSets,
|
|
3267
1313
|
buttonsVisible: optional(enumeration("always", "never", "focused"))
|
|
3268
1314
|
}));
|
|
3269
|
-
|
|
1315
|
+
function migrateV1ToV2$1(widget) {
|
|
1316
|
+
const {
|
|
1317
|
+
options
|
|
1318
|
+
} = widget;
|
|
1319
|
+
return {
|
|
1320
|
+
...widget,
|
|
1321
|
+
version: {
|
|
1322
|
+
major: 2,
|
|
1323
|
+
minor: 0
|
|
1324
|
+
},
|
|
1325
|
+
options: {
|
|
1326
|
+
times: options.times,
|
|
1327
|
+
buttonSets: options.buttonSets,
|
|
1328
|
+
functions: options.functions,
|
|
1329
|
+
buttonsVisible: options.buttonsVisible,
|
|
1330
|
+
visibleLabel: options.visibleLabel,
|
|
1331
|
+
ariaLabel: options.ariaLabel,
|
|
1332
|
+
answerForms: options.answerForms,
|
|
1333
|
+
extraKeys: deriveExtraKeys(options)
|
|
1334
|
+
}
|
|
1335
|
+
};
|
|
1336
|
+
}
|
|
1337
|
+
const version0$1 = optional(object({
|
|
3270
1338
|
major: constant(0),
|
|
3271
1339
|
minor: number
|
|
3272
1340
|
}));
|
|
3273
|
-
const parseExpressionWidgetV0 = parseWidgetWithVersion(version0, constant("expression"), object({
|
|
1341
|
+
const parseExpressionWidgetV0 = parseWidgetWithVersion(version0$1, constant("expression"), object({
|
|
3274
1342
|
functions: array(string),
|
|
3275
1343
|
times: boolean,
|
|
3276
1344
|
visibleLabel: optional(string),
|
|
@@ -3281,7 +1349,7 @@ const parseExpressionWidgetV0 = parseWidgetWithVersion(version0, constant("expre
|
|
|
3281
1349
|
buttonSets: parseLegacyButtonSets,
|
|
3282
1350
|
buttonsVisible: optional(enumeration("always", "never", "focused"))
|
|
3283
1351
|
}));
|
|
3284
|
-
function migrateV0ToV1(widget) {
|
|
1352
|
+
function migrateV0ToV1$1(widget) {
|
|
3285
1353
|
const {
|
|
3286
1354
|
options
|
|
3287
1355
|
} = widget;
|
|
@@ -3307,7 +1375,7 @@ function migrateV0ToV1(widget) {
|
|
|
3307
1375
|
}
|
|
3308
1376
|
};
|
|
3309
1377
|
}
|
|
3310
|
-
const parseExpressionWidget = versionedWidgetOptions(1, parseExpressionWidgetV1).withMigrationFrom(0, parseExpressionWidgetV0, migrateV0ToV1).parser;
|
|
1378
|
+
const parseExpressionWidget = versionedWidgetOptions(2, parseExpressionWidgetV2).withMigrationFrom(1, parseExpressionWidgetV1, migrateV1ToV2$1).withMigrationFrom(0, parseExpressionWidgetV0, migrateV0ToV1$1).parser;
|
|
3311
1379
|
|
|
3312
1380
|
const falseToNull = pipeParsers(constant(false)).then(convert(() => null)).parser;
|
|
3313
1381
|
const parseGradedGroupWidgetOptions = object({
|
|
@@ -4080,13 +2148,16 @@ const parseLockedPolygonType = object({
|
|
|
4080
2148
|
labels: optional(array(parseLockedLabelType)),
|
|
4081
2149
|
ariaLabel: optional(string)
|
|
4082
2150
|
});
|
|
2151
|
+
|
|
2152
|
+
// Exported for testing.
|
|
2153
|
+
const parseLockedFunctionDomain = defaulted(pair(defaulted(number, () => -Infinity), defaulted(number, () => Infinity)), () => [-Infinity, Infinity]);
|
|
4083
2154
|
const parseLockedFunctionType = object({
|
|
4084
2155
|
type: constant("function"),
|
|
4085
2156
|
color: parseLockedFigureColor,
|
|
4086
2157
|
strokeStyle: parseLockedLineStyle,
|
|
4087
2158
|
equation: string,
|
|
4088
2159
|
directionalAxis: enumeration("x", "y"),
|
|
4089
|
-
domain:
|
|
2160
|
+
domain: parseLockedFunctionDomain,
|
|
4090
2161
|
// TODO(benchristel): default labels to empty array?
|
|
4091
2162
|
labels: optional(array(parseLockedLabelType)),
|
|
4092
2163
|
ariaLabel: optional(string)
|
|
@@ -4206,6 +2277,7 @@ const parseNumberLineWidget = parseWidget(constant("number-line"), object({
|
|
|
4206
2277
|
}));
|
|
4207
2278
|
|
|
4208
2279
|
const parseMathFormat = enumeration("integer", "mixed", "improper", "proper", "decimal", "percent", "pi");
|
|
2280
|
+
const parseSimplify = enumeration("required", "correct", "enforced", "optional");
|
|
4209
2281
|
const parseNumericInputWidget = parseWidget(constant("numeric-input"), object({
|
|
4210
2282
|
answers: array(object({
|
|
4211
2283
|
message: string,
|
|
@@ -4220,7 +2292,12 @@ const parseNumericInputWidget = parseWidget(constant("numeric-input"), object({
|
|
|
4220
2292
|
// TODO(benchristel): simplify should never be a boolean, but we
|
|
4221
2293
|
// have some content where it is anyway. If we ever backfill
|
|
4222
2294
|
// the data, we should simplify `simplify`.
|
|
4223
|
-
simplify: optional(nullable(union(
|
|
2295
|
+
simplify: optional(nullable(union(parseSimplify).or(pipeParsers(boolean).then(convert(value => {
|
|
2296
|
+
if (typeof value === "boolean") {
|
|
2297
|
+
return value ? "required" : "optional";
|
|
2298
|
+
}
|
|
2299
|
+
return value;
|
|
2300
|
+
})).parser).parser))
|
|
4224
2301
|
})),
|
|
4225
2302
|
labelText: optional(string),
|
|
4226
2303
|
size: string,
|
|
@@ -4296,13 +2373,135 @@ const parsePlotterWidget = parseWidget(constant("plotter"), object({
|
|
|
4296
2373
|
// of why we want to duplicate the defaults here.
|
|
4297
2374
|
plotDimensions: defaulted(array(number), () => [380, 300])
|
|
4298
2375
|
}));
|
|
4299
|
-
|
|
4300
|
-
const parsePythonProgramWidget = parseWidget(constant("python-program"), object({
|
|
4301
|
-
programID: string,
|
|
4302
|
-
height: number
|
|
2376
|
+
|
|
2377
|
+
const parsePythonProgramWidget = parseWidget(constant("python-program"), object({
|
|
2378
|
+
programID: string,
|
|
2379
|
+
height: number
|
|
2380
|
+
}));
|
|
2381
|
+
|
|
2382
|
+
const currentVersion$3 = {
|
|
2383
|
+
major: 2,
|
|
2384
|
+
minor: 0
|
|
2385
|
+
};
|
|
2386
|
+
function deriveNumCorrect(options) {
|
|
2387
|
+
const {
|
|
2388
|
+
choices,
|
|
2389
|
+
numCorrect
|
|
2390
|
+
} = options;
|
|
2391
|
+
return numCorrect ?? choices.filter(c => c.correct).length;
|
|
2392
|
+
}
|
|
2393
|
+
const widgetOptionsUpgrades$2 = {
|
|
2394
|
+
"2": v1props => {
|
|
2395
|
+
const upgraded = {
|
|
2396
|
+
...v1props,
|
|
2397
|
+
numCorrect: deriveNumCorrect(v1props)
|
|
2398
|
+
};
|
|
2399
|
+
return upgraded;
|
|
2400
|
+
},
|
|
2401
|
+
"1": v0props => {
|
|
2402
|
+
const {
|
|
2403
|
+
noneOfTheAbove,
|
|
2404
|
+
...rest
|
|
2405
|
+
} = v0props;
|
|
2406
|
+
if (noneOfTheAbove) {
|
|
2407
|
+
throw new Error("radio widget v0 no longer supports auto noneOfTheAbove");
|
|
2408
|
+
}
|
|
2409
|
+
return {
|
|
2410
|
+
...rest,
|
|
2411
|
+
hasNoneOfTheAbove: false
|
|
2412
|
+
};
|
|
2413
|
+
}
|
|
2414
|
+
};
|
|
2415
|
+
const defaultWidgetOptions$v = {
|
|
2416
|
+
choices: [{}, {}, {}, {}],
|
|
2417
|
+
displayCount: null,
|
|
2418
|
+
randomize: false,
|
|
2419
|
+
hasNoneOfTheAbove: false,
|
|
2420
|
+
multipleSelect: false,
|
|
2421
|
+
countChoices: false,
|
|
2422
|
+
deselectEnabled: false
|
|
2423
|
+
};
|
|
2424
|
+
|
|
2425
|
+
const version2 = optional(object({
|
|
2426
|
+
major: constant(2),
|
|
2427
|
+
minor: number
|
|
2428
|
+
}));
|
|
2429
|
+
const parseRadioWidgetV2 = parseWidgetWithVersion(version2, constant("radio"), object({
|
|
2430
|
+
numCorrect: optional(number),
|
|
2431
|
+
choices: array(object({
|
|
2432
|
+
content: defaulted(string, () => ""),
|
|
2433
|
+
clue: optional(string),
|
|
2434
|
+
correct: optional(boolean),
|
|
2435
|
+
isNoneOfTheAbove: optional(boolean),
|
|
2436
|
+
// deprecated
|
|
2437
|
+
// There is an import cycle between radio-widget.ts and
|
|
2438
|
+
// widgets-map.ts. The anonymous function below ensures that we
|
|
2439
|
+
// don't refer to parseWidgetsMap before it's defined.
|
|
2440
|
+
widgets: optional((rawVal, ctx) => parseWidgetsMap(rawVal, ctx))
|
|
2441
|
+
})),
|
|
2442
|
+
hasNoneOfTheAbove: optional(boolean),
|
|
2443
|
+
countChoices: optional(boolean),
|
|
2444
|
+
randomize: optional(boolean),
|
|
2445
|
+
multipleSelect: optional(boolean),
|
|
2446
|
+
deselectEnabled: optional(boolean),
|
|
2447
|
+
// deprecated
|
|
2448
|
+
onePerLine: optional(boolean),
|
|
2449
|
+
// deprecated
|
|
2450
|
+
displayCount: optional(any),
|
|
2451
|
+
// v0 props
|
|
2452
|
+
// `noneOfTheAbove` is still in use (but only set to `false`).
|
|
2453
|
+
noneOfTheAbove: optional(constant(false))
|
|
2454
|
+
}));
|
|
2455
|
+
const version1 = optional(object({
|
|
2456
|
+
major: constant(1),
|
|
2457
|
+
minor: number
|
|
2458
|
+
}));
|
|
2459
|
+
const parseRadioWidgetV1 = parseWidgetWithVersion(version1, constant("radio"), object({
|
|
2460
|
+
choices: array(object({
|
|
2461
|
+
content: defaulted(string, () => ""),
|
|
2462
|
+
clue: optional(string),
|
|
2463
|
+
correct: optional(boolean),
|
|
2464
|
+
isNoneOfTheAbove: optional(boolean),
|
|
2465
|
+
// deprecated
|
|
2466
|
+
// There is an import cycle between radio-widget.ts and
|
|
2467
|
+
// widgets-map.ts. The anonymous function below ensures that we
|
|
2468
|
+
// don't refer to parseWidgetsMap before it's defined.
|
|
2469
|
+
widgets: defaulted((rawVal, ctx) => parseWidgetsMap(rawVal, ctx), () => undefined)
|
|
2470
|
+
})),
|
|
2471
|
+
hasNoneOfTheAbove: optional(boolean),
|
|
2472
|
+
countChoices: optional(boolean),
|
|
2473
|
+
randomize: optional(boolean),
|
|
2474
|
+
multipleSelect: optional(boolean),
|
|
2475
|
+
deselectEnabled: optional(boolean),
|
|
2476
|
+
// deprecated
|
|
2477
|
+
onePerLine: optional(boolean),
|
|
2478
|
+
// deprecated
|
|
2479
|
+
displayCount: optional(any),
|
|
2480
|
+
// v0 props
|
|
2481
|
+
// `noneOfTheAbove` is still in use (but only set to `false`).
|
|
2482
|
+
noneOfTheAbove: optional(constant(false))
|
|
2483
|
+
}));
|
|
2484
|
+
function migrateV1ToV2(widget) {
|
|
2485
|
+
const {
|
|
2486
|
+
options
|
|
2487
|
+
} = widget;
|
|
2488
|
+
return {
|
|
2489
|
+
...widget,
|
|
2490
|
+
version: {
|
|
2491
|
+
major: 2,
|
|
2492
|
+
minor: 0
|
|
2493
|
+
},
|
|
2494
|
+
options: {
|
|
2495
|
+
...options,
|
|
2496
|
+
numCorrect: deriveNumCorrect(options)
|
|
2497
|
+
}
|
|
2498
|
+
};
|
|
2499
|
+
}
|
|
2500
|
+
const version0 = optional(object({
|
|
2501
|
+
major: constant(0),
|
|
2502
|
+
minor: number
|
|
4303
2503
|
}));
|
|
4304
|
-
|
|
4305
|
-
const parseRadioWidget = parseWidget(constant("radio"), object({
|
|
2504
|
+
const parseRadioWidgetV0 = parseWidgetWithVersion(version0, constant("radio"), object({
|
|
4306
2505
|
choices: array(object({
|
|
4307
2506
|
content: defaulted(string, () => ""),
|
|
4308
2507
|
clue: optional(string),
|
|
@@ -4312,7 +2511,7 @@ const parseRadioWidget = parseWidget(constant("radio"), object({
|
|
|
4312
2511
|
// There is an import cycle between radio-widget.ts and
|
|
4313
2512
|
// widgets-map.ts. The anonymous function below ensures that we
|
|
4314
2513
|
// don't refer to parseWidgetsMap before it's defined.
|
|
4315
|
-
widgets:
|
|
2514
|
+
widgets: optional((rawVal, ctx) => parseWidgetsMap(rawVal, ctx))
|
|
4316
2515
|
})),
|
|
4317
2516
|
hasNoneOfTheAbove: optional(boolean),
|
|
4318
2517
|
countChoices: optional(boolean),
|
|
@@ -4327,6 +2526,27 @@ const parseRadioWidget = parseWidget(constant("radio"), object({
|
|
|
4327
2526
|
// `noneOfTheAbove` is still in use (but only set to `false`).
|
|
4328
2527
|
noneOfTheAbove: optional(constant(false))
|
|
4329
2528
|
}));
|
|
2529
|
+
function migrateV0ToV1(widget) {
|
|
2530
|
+
const {
|
|
2531
|
+
options
|
|
2532
|
+
} = widget;
|
|
2533
|
+
const {
|
|
2534
|
+
noneOfTheAbove: _,
|
|
2535
|
+
...rest
|
|
2536
|
+
} = options;
|
|
2537
|
+
return {
|
|
2538
|
+
...widget,
|
|
2539
|
+
version: {
|
|
2540
|
+
major: 1,
|
|
2541
|
+
minor: 0
|
|
2542
|
+
},
|
|
2543
|
+
options: {
|
|
2544
|
+
...rest,
|
|
2545
|
+
hasNoneOfTheAbove: false
|
|
2546
|
+
}
|
|
2547
|
+
};
|
|
2548
|
+
}
|
|
2549
|
+
const parseRadioWidget = versionedWidgetOptions(2, parseRadioWidgetV2).withMigrationFrom(1, parseRadioWidgetV1, migrateV1ToV2).withMigrationFrom(0, parseRadioWidgetV0, migrateV0ToV1).parser;
|
|
4330
2550
|
|
|
4331
2551
|
const parseSorterWidget = parseWidget(constant("sorter"), object({
|
|
4332
2552
|
correct: array(string),
|
|
@@ -4501,7 +2721,7 @@ const parsePerseusRenderer = defaulted(object({
|
|
|
4501
2721
|
const parsePerseusArticle = union(parsePerseusRenderer).or(array(parsePerseusRenderer)).parser;
|
|
4502
2722
|
|
|
4503
2723
|
const parseHint = object({
|
|
4504
|
-
replace:
|
|
2724
|
+
replace: defaulted(boolean, () => undefined),
|
|
4505
2725
|
content: string,
|
|
4506
2726
|
widgets: defaulted(parseWidgetsMap, () => ({})),
|
|
4507
2727
|
images: parseImages,
|
|
@@ -4622,9 +2842,50 @@ function throwErrorIfCheatingDetected() {
|
|
|
4622
2842
|
}
|
|
4623
2843
|
}
|
|
4624
2844
|
|
|
2845
|
+
/**
|
|
2846
|
+
* Adds the given perseus library version information to the __perseus_debug__
|
|
2847
|
+
* object and ensures that the object is attached to `globalThis` (`window` in
|
|
2848
|
+
* browser environments).
|
|
2849
|
+
*
|
|
2850
|
+
* This allows each library to provide runtime version information to assist in
|
|
2851
|
+
* debugging in production environments.
|
|
2852
|
+
*/
|
|
2853
|
+
const addLibraryVersionToPerseusDebug = (libraryName, libraryVersion) => {
|
|
2854
|
+
// If the library version is the default value, then we don't want to
|
|
2855
|
+
// prefix it with a "v" to indicate that it is a version number.
|
|
2856
|
+
let prefix = "v";
|
|
2857
|
+
if (libraryVersion === "__lib_version__") {
|
|
2858
|
+
prefix = "";
|
|
2859
|
+
}
|
|
2860
|
+
const formattedVersion = `${prefix}${libraryVersion}`;
|
|
2861
|
+
if (typeof globalThis !== "undefined") {
|
|
2862
|
+
globalThis.__perseus_debug__ = globalThis.__perseus_debug__ ?? {};
|
|
2863
|
+
const existingVersionEntry = globalThis.__perseus_debug__[libraryName];
|
|
2864
|
+
if (existingVersionEntry) {
|
|
2865
|
+
// If we already have an entry and it doesn't match the registered
|
|
2866
|
+
// version, we morph the entry into an array and log a warning.
|
|
2867
|
+
if (existingVersionEntry !== formattedVersion) {
|
|
2868
|
+
// Existing entry might be an array already (oops, at least 2
|
|
2869
|
+
// versions of the library already loaded!).
|
|
2870
|
+
const allVersions = Array.isArray(existingVersionEntry) ? existingVersionEntry : [existingVersionEntry];
|
|
2871
|
+
allVersions.push(formattedVersion);
|
|
2872
|
+
globalThis.__perseus_debug__[libraryName] = allVersions;
|
|
2873
|
+
|
|
2874
|
+
// eslint-disable-next-line no-console
|
|
2875
|
+
console.warn(`Multiple versions of ${libraryName} loaded on this page: ${allVersions.sort().join(", ")}`);
|
|
2876
|
+
}
|
|
2877
|
+
} else {
|
|
2878
|
+
globalThis.__perseus_debug__[libraryName] = formattedVersion;
|
|
2879
|
+
}
|
|
2880
|
+
} else {
|
|
2881
|
+
// eslint-disable-next-line no-console
|
|
2882
|
+
console.warn(`globalThis not found found (${formattedVersion})`);
|
|
2883
|
+
}
|
|
2884
|
+
};
|
|
2885
|
+
|
|
4625
2886
|
// This file is processed by a Rollup plugin (replace) to inject the production
|
|
4626
2887
|
const libName = "@khanacademy/perseus-core";
|
|
4627
|
-
const libVersion = "
|
|
2888
|
+
const libVersion = "5.0.0";
|
|
4628
2889
|
addLibraryVersionToPerseusDebug(libName, libVersion);
|
|
4629
2890
|
|
|
4630
2891
|
/**
|
|
@@ -4701,7 +2962,7 @@ class PerseusError extends Error {
|
|
|
4701
2962
|
* }
|
|
4702
2963
|
*/
|
|
4703
2964
|
const pluck = function (table, subKey) {
|
|
4704
|
-
return
|
|
2965
|
+
return ___default["default"].object(___default["default"].map(table, function (value, key) {
|
|
4705
2966
|
return [key, value[subKey]];
|
|
4706
2967
|
}));
|
|
4707
2968
|
};
|
|
@@ -4741,7 +3002,7 @@ function getCategorizerPublicWidgetOptions(options) {
|
|
|
4741
3002
|
};
|
|
4742
3003
|
}
|
|
4743
3004
|
|
|
4744
|
-
const defaultWidgetOptions$
|
|
3005
|
+
const defaultWidgetOptions$u = {
|
|
4745
3006
|
items: [],
|
|
4746
3007
|
categories: [],
|
|
4747
3008
|
values: [],
|
|
@@ -4749,7 +3010,7 @@ const defaultWidgetOptions$v = {
|
|
|
4749
3010
|
};
|
|
4750
3011
|
const categorizerWidgetLogic = {
|
|
4751
3012
|
name: "categorizer",
|
|
4752
|
-
defaultWidgetOptions: defaultWidgetOptions$
|
|
3013
|
+
defaultWidgetOptions: defaultWidgetOptions$u,
|
|
4753
3014
|
getPublicWidgetOptions: getCategorizerPublicWidgetOptions
|
|
4754
3015
|
};
|
|
4755
3016
|
|
|
@@ -4758,7 +3019,7 @@ function getCSProgramPublicWidgetOptions(options) {
|
|
|
4758
3019
|
}
|
|
4759
3020
|
|
|
4760
3021
|
const DEFAULT_HEIGHT = 400;
|
|
4761
|
-
const defaultWidgetOptions$
|
|
3022
|
+
const defaultWidgetOptions$t = {
|
|
4762
3023
|
programID: "",
|
|
4763
3024
|
programType: null,
|
|
4764
3025
|
settings: [{
|
|
@@ -4771,18 +3032,18 @@ const defaultWidgetOptions$u = {
|
|
|
4771
3032
|
};
|
|
4772
3033
|
const csProgramWidgetLogic = {
|
|
4773
3034
|
name: "cs-program",
|
|
4774
|
-
defaultWidgetOptions: defaultWidgetOptions$
|
|
3035
|
+
defaultWidgetOptions: defaultWidgetOptions$t,
|
|
4775
3036
|
supportedAlignments: ["block", "full-width"],
|
|
4776
3037
|
getPublicWidgetOptions: getCSProgramPublicWidgetOptions
|
|
4777
3038
|
};
|
|
4778
3039
|
|
|
4779
|
-
const defaultWidgetOptions$
|
|
3040
|
+
const defaultWidgetOptions$s = {
|
|
4780
3041
|
togglePrompt: "",
|
|
4781
3042
|
definition: ""
|
|
4782
3043
|
};
|
|
4783
3044
|
const definitionWidgetLogic = {
|
|
4784
3045
|
name: "definition",
|
|
4785
|
-
defaultWidgetOptions: defaultWidgetOptions$
|
|
3046
|
+
defaultWidgetOptions: defaultWidgetOptions$s,
|
|
4786
3047
|
defaultAlignment: "inline"
|
|
4787
3048
|
};
|
|
4788
3049
|
|
|
@@ -4807,7 +3068,7 @@ function getDropdownPublicWidgetOptions(options) {
|
|
|
4807
3068
|
};
|
|
4808
3069
|
}
|
|
4809
3070
|
|
|
4810
|
-
const defaultWidgetOptions$
|
|
3071
|
+
const defaultWidgetOptions$r = {
|
|
4811
3072
|
placeholder: "",
|
|
4812
3073
|
choices: [{
|
|
4813
3074
|
content: "",
|
|
@@ -4816,12 +3077,12 @@ const defaultWidgetOptions$s = {
|
|
|
4816
3077
|
};
|
|
4817
3078
|
const dropdownWidgetLogic = {
|
|
4818
3079
|
name: "definition",
|
|
4819
|
-
defaultWidgetOptions: defaultWidgetOptions$
|
|
3080
|
+
defaultWidgetOptions: defaultWidgetOptions$r,
|
|
4820
3081
|
defaultAlignment: "inline-block",
|
|
4821
3082
|
getPublicWidgetOptions: getDropdownPublicWidgetOptions
|
|
4822
3083
|
};
|
|
4823
3084
|
|
|
4824
|
-
const defaultWidgetOptions$
|
|
3085
|
+
const defaultWidgetOptions$q = {
|
|
4825
3086
|
showPrompt: "Explain",
|
|
4826
3087
|
hidePrompt: "Hide explanation",
|
|
4827
3088
|
explanation: "explanation goes here\n\nmore explanation",
|
|
@@ -4829,31 +3090,46 @@ const defaultWidgetOptions$r = {
|
|
|
4829
3090
|
};
|
|
4830
3091
|
const explanationWidgetLogic = {
|
|
4831
3092
|
name: "explanation",
|
|
4832
|
-
defaultWidgetOptions: defaultWidgetOptions$
|
|
3093
|
+
defaultWidgetOptions: defaultWidgetOptions$q,
|
|
4833
3094
|
defaultAlignment: "inline"
|
|
4834
3095
|
};
|
|
4835
3096
|
|
|
4836
|
-
const currentVersion$
|
|
4837
|
-
major:
|
|
3097
|
+
const currentVersion$2 = {
|
|
3098
|
+
major: 2,
|
|
4838
3099
|
minor: 0
|
|
4839
3100
|
};
|
|
4840
|
-
const widgetOptionsUpgrades$
|
|
4841
|
-
"
|
|
4842
|
-
|
|
4843
|
-
|
|
4844
|
-
|
|
4845
|
-
|
|
4846
|
-
|
|
4847
|
-
|
|
4848
|
-
|
|
4849
|
-
|
|
4850
|
-
|
|
4851
|
-
|
|
4852
|
-
|
|
4853
|
-
|
|
4854
|
-
|
|
3101
|
+
const widgetOptionsUpgrades$1 = {
|
|
3102
|
+
"2": v1options => {
|
|
3103
|
+
return {
|
|
3104
|
+
times: v1options.times,
|
|
3105
|
+
buttonSets: v1options.buttonSets,
|
|
3106
|
+
functions: v1options.functions,
|
|
3107
|
+
buttonsVisible: v1options.buttonsVisible,
|
|
3108
|
+
visibleLabel: v1options.visibleLabel,
|
|
3109
|
+
ariaLabel: v1options.ariaLabel,
|
|
3110
|
+
answerForms: v1options.answerForms,
|
|
3111
|
+
extraKeys: v1options.extraKeys || deriveExtraKeys(v1options)
|
|
3112
|
+
};
|
|
3113
|
+
},
|
|
3114
|
+
"1": v0options => {
|
|
3115
|
+
return {
|
|
3116
|
+
times: v0options.times,
|
|
3117
|
+
buttonSets: v0options.buttonSets,
|
|
3118
|
+
functions: v0options.functions,
|
|
3119
|
+
buttonsVisible: v0options.buttonsVisible,
|
|
3120
|
+
visibleLabel: v0options.visibleLabel,
|
|
3121
|
+
ariaLabel: v0options.ariaLabel,
|
|
3122
|
+
extraKeys: v0options.extraKeys,
|
|
3123
|
+
answerForms: [{
|
|
3124
|
+
considered: "correct",
|
|
3125
|
+
form: v0options.form,
|
|
3126
|
+
simplify: v0options.simplify,
|
|
3127
|
+
value: v0options.value
|
|
3128
|
+
}]
|
|
3129
|
+
};
|
|
3130
|
+
}
|
|
4855
3131
|
};
|
|
4856
|
-
const defaultWidgetOptions$
|
|
3132
|
+
const defaultWidgetOptions$p = {
|
|
4857
3133
|
answerForms: [],
|
|
4858
3134
|
times: false,
|
|
4859
3135
|
buttonSets: ["basic"],
|
|
@@ -4876,20 +3152,21 @@ function getExpressionPublicWidgetOptions(options) {
|
|
|
4876
3152
|
times: options.times,
|
|
4877
3153
|
visibleLabel: options.visibleLabel,
|
|
4878
3154
|
ariaLabel: options.ariaLabel,
|
|
4879
|
-
buttonsVisible: options.buttonsVisible
|
|
3155
|
+
buttonsVisible: options.buttonsVisible,
|
|
3156
|
+
extraKeys: options.extraKeys
|
|
4880
3157
|
};
|
|
4881
3158
|
}
|
|
4882
3159
|
|
|
4883
3160
|
const expressionWidgetLogic = {
|
|
4884
3161
|
name: "expression",
|
|
4885
|
-
version: currentVersion$
|
|
4886
|
-
widgetOptionsUpgrades: widgetOptionsUpgrades$
|
|
4887
|
-
defaultWidgetOptions: defaultWidgetOptions$
|
|
3162
|
+
version: currentVersion$2,
|
|
3163
|
+
widgetOptionsUpgrades: widgetOptionsUpgrades$1,
|
|
3164
|
+
defaultWidgetOptions: defaultWidgetOptions$p,
|
|
4888
3165
|
defaultAlignment: "inline-block",
|
|
4889
3166
|
getPublicWidgetOptions: getExpressionPublicWidgetOptions
|
|
4890
3167
|
};
|
|
4891
3168
|
|
|
4892
|
-
const defaultWidgetOptions$
|
|
3169
|
+
const defaultWidgetOptions$o = {
|
|
4893
3170
|
title: "",
|
|
4894
3171
|
content: "",
|
|
4895
3172
|
widgets: {},
|
|
@@ -4898,15 +3175,15 @@ const defaultWidgetOptions$p = {
|
|
|
4898
3175
|
};
|
|
4899
3176
|
const gradedGroupWidgetLogic = {
|
|
4900
3177
|
name: "graded-group",
|
|
4901
|
-
defaultWidgetOptions: defaultWidgetOptions$
|
|
3178
|
+
defaultWidgetOptions: defaultWidgetOptions$o
|
|
4902
3179
|
};
|
|
4903
3180
|
|
|
4904
|
-
const defaultWidgetOptions$
|
|
3181
|
+
const defaultWidgetOptions$n = {
|
|
4905
3182
|
gradedGroups: []
|
|
4906
3183
|
};
|
|
4907
3184
|
const gradedGroupSetWidgetLogic = {
|
|
4908
3185
|
name: "graded-group-set",
|
|
4909
|
-
defaultWidgetOptions: defaultWidgetOptions$
|
|
3186
|
+
defaultWidgetOptions: defaultWidgetOptions$n
|
|
4910
3187
|
};
|
|
4911
3188
|
|
|
4912
3189
|
function getGrapherPublicWidgetOptions(options) {
|
|
@@ -4917,7 +3194,7 @@ function getGrapherPublicWidgetOptions(options) {
|
|
|
4917
3194
|
return publicOptions;
|
|
4918
3195
|
}
|
|
4919
3196
|
|
|
4920
|
-
const defaultWidgetOptions$
|
|
3197
|
+
const defaultWidgetOptions$m = {
|
|
4921
3198
|
graph: {
|
|
4922
3199
|
labels: ["x", "y"],
|
|
4923
3200
|
range: [[-10, 10], [-10, 10]],
|
|
@@ -4939,25 +3216,25 @@ const defaultWidgetOptions$n = {
|
|
|
4939
3216
|
};
|
|
4940
3217
|
const grapherWidgetLogic = {
|
|
4941
3218
|
name: "grapher",
|
|
4942
|
-
defaultWidgetOptions: defaultWidgetOptions$
|
|
3219
|
+
defaultWidgetOptions: defaultWidgetOptions$m,
|
|
4943
3220
|
getPublicWidgetOptions: getGrapherPublicWidgetOptions
|
|
4944
3221
|
};
|
|
4945
3222
|
|
|
4946
|
-
const defaultWidgetOptions$
|
|
3223
|
+
const defaultWidgetOptions$l = {
|
|
4947
3224
|
content: "",
|
|
4948
3225
|
widgets: {},
|
|
4949
3226
|
images: {}
|
|
4950
3227
|
};
|
|
4951
3228
|
const groupWidgetLogic = {
|
|
4952
3229
|
name: "group",
|
|
4953
|
-
defaultWidgetOptions: defaultWidgetOptions$
|
|
3230
|
+
defaultWidgetOptions: defaultWidgetOptions$l
|
|
4954
3231
|
};
|
|
4955
3232
|
|
|
4956
3233
|
function getIFramePublicWidgetOptions(options) {
|
|
4957
3234
|
return options;
|
|
4958
3235
|
}
|
|
4959
3236
|
|
|
4960
|
-
const defaultWidgetOptions$
|
|
3237
|
+
const defaultWidgetOptions$k = {
|
|
4961
3238
|
url: "",
|
|
4962
3239
|
settings: [{
|
|
4963
3240
|
name: "",
|
|
@@ -4970,11 +3247,11 @@ const defaultWidgetOptions$l = {
|
|
|
4970
3247
|
};
|
|
4971
3248
|
const iframeWidgetLogic = {
|
|
4972
3249
|
name: "iframe",
|
|
4973
|
-
defaultWidgetOptions: defaultWidgetOptions$
|
|
3250
|
+
defaultWidgetOptions: defaultWidgetOptions$k,
|
|
4974
3251
|
getPublicWidgetOptions: getIFramePublicWidgetOptions
|
|
4975
3252
|
};
|
|
4976
3253
|
|
|
4977
|
-
const defaultWidgetOptions$
|
|
3254
|
+
const defaultWidgetOptions$j = {
|
|
4978
3255
|
title: "",
|
|
4979
3256
|
range: [[0, 10], [0, 10]],
|
|
4980
3257
|
box: [400, 400],
|
|
@@ -4989,12 +3266,12 @@ const defaultWidgetOptions$k = {
|
|
|
4989
3266
|
};
|
|
4990
3267
|
const imageWidgetLogic = {
|
|
4991
3268
|
name: "image",
|
|
4992
|
-
defaultWidgetOptions: defaultWidgetOptions$
|
|
3269
|
+
defaultWidgetOptions: defaultWidgetOptions$j,
|
|
4993
3270
|
supportedAlignments: ["block", "full-width"],
|
|
4994
3271
|
defaultAlignment: "block"
|
|
4995
3272
|
};
|
|
4996
3273
|
|
|
4997
|
-
const defaultWidgetOptions$
|
|
3274
|
+
const defaultWidgetOptions$i = {
|
|
4998
3275
|
value: 0,
|
|
4999
3276
|
simplify: "required",
|
|
5000
3277
|
size: "normal",
|
|
@@ -5005,11 +3282,11 @@ const defaultWidgetOptions$j = {
|
|
|
5005
3282
|
};
|
|
5006
3283
|
const inputNumberWidgetLogic = {
|
|
5007
3284
|
name: "input-number",
|
|
5008
|
-
defaultWidgetOptions: defaultWidgetOptions$
|
|
3285
|
+
defaultWidgetOptions: defaultWidgetOptions$i,
|
|
5009
3286
|
defaultAlignment: "inline-block"
|
|
5010
3287
|
};
|
|
5011
3288
|
|
|
5012
|
-
const defaultWidgetOptions$
|
|
3289
|
+
const defaultWidgetOptions$h = {
|
|
5013
3290
|
graph: {
|
|
5014
3291
|
box: [400, 400],
|
|
5015
3292
|
labels: ["x", "y"],
|
|
@@ -5022,7 +3299,7 @@ const defaultWidgetOptions$i = {
|
|
|
5022
3299
|
};
|
|
5023
3300
|
const interactionWidgetLogic = {
|
|
5024
3301
|
name: "interaction",
|
|
5025
|
-
defaultWidgetOptions: defaultWidgetOptions$
|
|
3302
|
+
defaultWidgetOptions: defaultWidgetOptions$h
|
|
5026
3303
|
};
|
|
5027
3304
|
|
|
5028
3305
|
function getInteractiveGraphPublicWidgetOptions(options) {
|
|
@@ -5033,7 +3310,7 @@ function getInteractiveGraphPublicWidgetOptions(options) {
|
|
|
5033
3310
|
return publicOptions;
|
|
5034
3311
|
}
|
|
5035
3312
|
|
|
5036
|
-
const defaultWidgetOptions$
|
|
3313
|
+
const defaultWidgetOptions$g = {
|
|
5037
3314
|
labels: ["x", "y"],
|
|
5038
3315
|
range: [[-10, 10], [-10, 10]],
|
|
5039
3316
|
step: [1, 1],
|
|
@@ -5053,7 +3330,7 @@ const defaultWidgetOptions$h = {
|
|
|
5053
3330
|
};
|
|
5054
3331
|
const interactiveGraphWidgetLogic = {
|
|
5055
3332
|
name: "interactive-graph",
|
|
5056
|
-
defaultWidgetOptions: defaultWidgetOptions$
|
|
3333
|
+
defaultWidgetOptions: defaultWidgetOptions$g,
|
|
5057
3334
|
getPublicWidgetOptions: getInteractiveGraphPublicWidgetOptions
|
|
5058
3335
|
};
|
|
5059
3336
|
|
|
@@ -5076,7 +3353,7 @@ function getLabelImageMarkerPublicData(marker) {
|
|
|
5076
3353
|
return publicData;
|
|
5077
3354
|
}
|
|
5078
3355
|
|
|
5079
|
-
const defaultWidgetOptions$
|
|
3356
|
+
const defaultWidgetOptions$f = {
|
|
5080
3357
|
choices: [],
|
|
5081
3358
|
imageAlt: "",
|
|
5082
3359
|
imageUrl: "",
|
|
@@ -5088,7 +3365,7 @@ const defaultWidgetOptions$g = {
|
|
|
5088
3365
|
};
|
|
5089
3366
|
const labelImageWidgetLogic = {
|
|
5090
3367
|
name: "label-image",
|
|
5091
|
-
defaultWidgetOptions: defaultWidgetOptions$
|
|
3368
|
+
defaultWidgetOptions: defaultWidgetOptions$f,
|
|
5092
3369
|
getPublicWidgetOptions: getLabelImagePublicWidgetOptions
|
|
5093
3370
|
};
|
|
5094
3371
|
|
|
@@ -5150,7 +3427,7 @@ function getMatcherPublicWidgetOptions(options) {
|
|
|
5150
3427
|
};
|
|
5151
3428
|
}
|
|
5152
3429
|
|
|
5153
|
-
const defaultWidgetOptions$
|
|
3430
|
+
const defaultWidgetOptions$e = {
|
|
5154
3431
|
left: ["$x$", "$y$", "$z$"],
|
|
5155
3432
|
right: ["$1$", "$2$", "$3$"],
|
|
5156
3433
|
labels: ["test", "label"],
|
|
@@ -5159,7 +3436,7 @@ const defaultWidgetOptions$f = {
|
|
|
5159
3436
|
};
|
|
5160
3437
|
const matcherWidgetLogic = {
|
|
5161
3438
|
name: "matcher",
|
|
5162
|
-
defaultWidgetOptions: defaultWidgetOptions$
|
|
3439
|
+
defaultWidgetOptions: defaultWidgetOptions$e,
|
|
5163
3440
|
getPublicWidgetOptions: getMatcherPublicWidgetOptions
|
|
5164
3441
|
};
|
|
5165
3442
|
|
|
@@ -5171,7 +3448,7 @@ function getMatrixPublicWidgetOptions(options) {
|
|
|
5171
3448
|
return publicOptions;
|
|
5172
3449
|
}
|
|
5173
3450
|
|
|
5174
|
-
const defaultWidgetOptions$
|
|
3451
|
+
const defaultWidgetOptions$d = {
|
|
5175
3452
|
matrixBoardSize: [3, 3],
|
|
5176
3453
|
answers: [[]],
|
|
5177
3454
|
prefix: "",
|
|
@@ -5180,15 +3457,15 @@ const defaultWidgetOptions$e = {
|
|
|
5180
3457
|
};
|
|
5181
3458
|
const matrixWidgetLogic = {
|
|
5182
3459
|
name: "matrix",
|
|
5183
|
-
defaultWidgetOptions: defaultWidgetOptions$
|
|
3460
|
+
defaultWidgetOptions: defaultWidgetOptions$d,
|
|
5184
3461
|
getPublicWidgetOptions: getMatrixPublicWidgetOptions
|
|
5185
3462
|
};
|
|
5186
3463
|
|
|
5187
|
-
const currentVersion$
|
|
3464
|
+
const currentVersion$1 = {
|
|
5188
3465
|
major: 1,
|
|
5189
3466
|
minor: 0
|
|
5190
3467
|
};
|
|
5191
|
-
const widgetOptionsUpgrades
|
|
3468
|
+
const widgetOptionsUpgrades = {
|
|
5192
3469
|
"1": v0options => {
|
|
5193
3470
|
const {
|
|
5194
3471
|
imageUrl,
|
|
@@ -5206,7 +3483,7 @@ const widgetOptionsUpgrades$1 = {
|
|
|
5206
3483
|
};
|
|
5207
3484
|
}
|
|
5208
3485
|
};
|
|
5209
|
-
const defaultWidgetOptions$
|
|
3486
|
+
const defaultWidgetOptions$c = {
|
|
5210
3487
|
box: [480, 480],
|
|
5211
3488
|
image: {},
|
|
5212
3489
|
showProtractor: true,
|
|
@@ -5219,9 +3496,9 @@ const defaultWidgetOptions$d = {
|
|
|
5219
3496
|
|
|
5220
3497
|
const measurerWidgetLogic = {
|
|
5221
3498
|
name: "measurer",
|
|
5222
|
-
version: currentVersion$
|
|
5223
|
-
widgetOptionsUpgrades: widgetOptionsUpgrades
|
|
5224
|
-
defaultWidgetOptions: defaultWidgetOptions$
|
|
3499
|
+
version: currentVersion$1,
|
|
3500
|
+
widgetOptionsUpgrades: widgetOptionsUpgrades,
|
|
3501
|
+
defaultWidgetOptions: defaultWidgetOptions$c
|
|
5225
3502
|
};
|
|
5226
3503
|
|
|
5227
3504
|
function getNumberLinePublicWidgetOptions(options) {
|
|
@@ -5233,7 +3510,7 @@ function getNumberLinePublicWidgetOptions(options) {
|
|
|
5233
3510
|
return publicOptions;
|
|
5234
3511
|
}
|
|
5235
3512
|
|
|
5236
|
-
const defaultWidgetOptions$
|
|
3513
|
+
const defaultWidgetOptions$b = {
|
|
5237
3514
|
range: [0, 10],
|
|
5238
3515
|
labelRange: [null, null],
|
|
5239
3516
|
labelStyle: "decimal",
|
|
@@ -5249,7 +3526,7 @@ const defaultWidgetOptions$c = {
|
|
|
5249
3526
|
};
|
|
5250
3527
|
const numberLineWidgetLogic = {
|
|
5251
3528
|
name: "number-line",
|
|
5252
|
-
defaultWidgetOptions: defaultWidgetOptions$
|
|
3529
|
+
defaultWidgetOptions: defaultWidgetOptions$b,
|
|
5253
3530
|
getPublicWidgetOptions: getNumberLinePublicWidgetOptions
|
|
5254
3531
|
};
|
|
5255
3532
|
|
|
@@ -5258,19 +3535,39 @@ const numberLineWidgetLogic = {
|
|
|
5258
3535
|
* PerseusNumericInputWidgetOptions type
|
|
5259
3536
|
*/
|
|
5260
3537
|
|
|
3538
|
+
/**
|
|
3539
|
+
* This data from `answers` is used pre-scoring to give hints
|
|
3540
|
+
* to the learner regarding the format of accepted answers
|
|
3541
|
+
*/
|
|
3542
|
+
function getNumericInputAnswerPublicData(answer) {
|
|
3543
|
+
const {
|
|
3544
|
+
answerForms,
|
|
3545
|
+
simplify,
|
|
3546
|
+
status
|
|
3547
|
+
} = answer;
|
|
3548
|
+
return {
|
|
3549
|
+
answerForms,
|
|
3550
|
+
simplify,
|
|
3551
|
+
status
|
|
3552
|
+
};
|
|
3553
|
+
}
|
|
3554
|
+
|
|
5261
3555
|
/**
|
|
5262
3556
|
* Given a PerseusNumericInputWidgetOptions object, return a new object with only
|
|
5263
3557
|
* the public options that should be exposed to the client.
|
|
5264
3558
|
*/
|
|
5265
3559
|
function getNumericInputPublicWidgetOptions(options) {
|
|
5266
3560
|
const {
|
|
5267
|
-
answers
|
|
3561
|
+
answers,
|
|
5268
3562
|
...publicWidgetOptions
|
|
5269
3563
|
} = options;
|
|
5270
|
-
return
|
|
3564
|
+
return {
|
|
3565
|
+
...publicWidgetOptions,
|
|
3566
|
+
answers: answers.map(getNumericInputAnswerPublicData)
|
|
3567
|
+
};
|
|
5271
3568
|
}
|
|
5272
3569
|
|
|
5273
|
-
const defaultWidgetOptions$
|
|
3570
|
+
const defaultWidgetOptions$a = {
|
|
5274
3571
|
answers: [{
|
|
5275
3572
|
value: null,
|
|
5276
3573
|
status: "correct",
|
|
@@ -5287,7 +3584,7 @@ const defaultWidgetOptions$b = {
|
|
|
5287
3584
|
};
|
|
5288
3585
|
const numericInputWidgetLogic = {
|
|
5289
3586
|
name: "numeric-input",
|
|
5290
|
-
defaultWidgetOptions: defaultWidgetOptions$
|
|
3587
|
+
defaultWidgetOptions: defaultWidgetOptions$a,
|
|
5291
3588
|
defaultAlignment: "inline-block",
|
|
5292
3589
|
getPublicWidgetOptions: getNumericInputPublicWidgetOptions
|
|
5293
3590
|
};
|
|
@@ -5309,7 +3606,7 @@ function getOrdererPublicWidgetOptions(options) {
|
|
|
5309
3606
|
};
|
|
5310
3607
|
}
|
|
5311
3608
|
|
|
5312
|
-
const defaultWidgetOptions$
|
|
3609
|
+
const defaultWidgetOptions$9 = {
|
|
5313
3610
|
correctOptions: [{
|
|
5314
3611
|
content: "$x$"
|
|
5315
3612
|
}],
|
|
@@ -5321,11 +3618,11 @@ const defaultWidgetOptions$a = {
|
|
|
5321
3618
|
};
|
|
5322
3619
|
const ordererWidgetLogic = {
|
|
5323
3620
|
name: "orderer",
|
|
5324
|
-
defaultWidgetOptions: defaultWidgetOptions$
|
|
3621
|
+
defaultWidgetOptions: defaultWidgetOptions$9,
|
|
5325
3622
|
getPublicWidgetOptions: getOrdererPublicWidgetOptions
|
|
5326
3623
|
};
|
|
5327
3624
|
|
|
5328
|
-
const defaultWidgetOptions$
|
|
3625
|
+
const defaultWidgetOptions$8 = {
|
|
5329
3626
|
passageTitle: "",
|
|
5330
3627
|
passageText: "",
|
|
5331
3628
|
footnotes: "",
|
|
@@ -5333,14 +3630,14 @@ const defaultWidgetOptions$9 = {
|
|
|
5333
3630
|
};
|
|
5334
3631
|
const passageWidgetLogic = {
|
|
5335
3632
|
name: "passage",
|
|
5336
|
-
defaultWidgetOptions: defaultWidgetOptions$
|
|
3633
|
+
defaultWidgetOptions: defaultWidgetOptions$8
|
|
5337
3634
|
};
|
|
5338
3635
|
|
|
5339
|
-
const currentVersion
|
|
3636
|
+
const currentVersion = {
|
|
5340
3637
|
major: 0,
|
|
5341
3638
|
minor: 1
|
|
5342
3639
|
};
|
|
5343
|
-
const defaultWidgetOptions$
|
|
3640
|
+
const defaultWidgetOptions$7 = {
|
|
5344
3641
|
passageNumber: 1,
|
|
5345
3642
|
referenceNumber: 1,
|
|
5346
3643
|
summaryText: ""
|
|
@@ -5348,27 +3645,27 @@ const defaultWidgetOptions$8 = {
|
|
|
5348
3645
|
|
|
5349
3646
|
const passageRefWidgetLogic = {
|
|
5350
3647
|
name: "passageRef",
|
|
5351
|
-
version: currentVersion
|
|
5352
|
-
defaultWidgetOptions: defaultWidgetOptions$
|
|
3648
|
+
version: currentVersion,
|
|
3649
|
+
defaultWidgetOptions: defaultWidgetOptions$7,
|
|
5353
3650
|
defaultAlignment: "inline"
|
|
5354
3651
|
};
|
|
5355
3652
|
|
|
5356
|
-
const defaultWidgetOptions$
|
|
3653
|
+
const defaultWidgetOptions$6 = {
|
|
5357
3654
|
content: ""
|
|
5358
3655
|
};
|
|
5359
3656
|
const passageRefTargetWidgetLogic = {
|
|
5360
3657
|
name: "passageRefTarget",
|
|
5361
|
-
defaultWidgetOptions: defaultWidgetOptions$
|
|
3658
|
+
defaultWidgetOptions: defaultWidgetOptions$6,
|
|
5362
3659
|
defaultAlignment: "inline"
|
|
5363
3660
|
};
|
|
5364
3661
|
|
|
5365
|
-
const defaultWidgetOptions$
|
|
3662
|
+
const defaultWidgetOptions$5 = {
|
|
5366
3663
|
url: "",
|
|
5367
3664
|
description: ""
|
|
5368
3665
|
};
|
|
5369
3666
|
const phetSimulationWidgetLogic = {
|
|
5370
3667
|
name: "phet-simulation",
|
|
5371
|
-
defaultWidgetOptions: defaultWidgetOptions$
|
|
3668
|
+
defaultWidgetOptions: defaultWidgetOptions$5
|
|
5372
3669
|
};
|
|
5373
3670
|
|
|
5374
3671
|
/**
|
|
@@ -5388,7 +3685,7 @@ function getPlotterPublicWidgetOptions(options) {
|
|
|
5388
3685
|
return publicOptions;
|
|
5389
3686
|
}
|
|
5390
3687
|
|
|
5391
|
-
const defaultWidgetOptions$
|
|
3688
|
+
const defaultWidgetOptions$4 = {
|
|
5392
3689
|
scaleY: 1,
|
|
5393
3690
|
maxY: 10,
|
|
5394
3691
|
snapsPerLine: 2,
|
|
@@ -5405,46 +3702,17 @@ const defaultWidgetOptions$5 = {
|
|
|
5405
3702
|
};
|
|
5406
3703
|
const plotterWidgetLogic = {
|
|
5407
3704
|
name: "plotter",
|
|
5408
|
-
defaultWidgetOptions: defaultWidgetOptions$
|
|
3705
|
+
defaultWidgetOptions: defaultWidgetOptions$4,
|
|
5409
3706
|
getPublicWidgetOptions: getPlotterPublicWidgetOptions
|
|
5410
3707
|
};
|
|
5411
3708
|
|
|
5412
|
-
const defaultWidgetOptions$
|
|
3709
|
+
const defaultWidgetOptions$3 = {
|
|
5413
3710
|
programID: "",
|
|
5414
3711
|
height: 400
|
|
5415
3712
|
};
|
|
5416
3713
|
const pythonProgramWidgetLogic = {
|
|
5417
3714
|
name: "python-program",
|
|
5418
|
-
defaultWidgetOptions: defaultWidgetOptions$
|
|
5419
|
-
};
|
|
5420
|
-
|
|
5421
|
-
const currentVersion = {
|
|
5422
|
-
major: 1,
|
|
5423
|
-
minor: 0
|
|
5424
|
-
};
|
|
5425
|
-
const widgetOptionsUpgrades = {
|
|
5426
|
-
"1": v0props => {
|
|
5427
|
-
const {
|
|
5428
|
-
noneOfTheAbove,
|
|
5429
|
-
...rest
|
|
5430
|
-
} = v0props;
|
|
5431
|
-
if (noneOfTheAbove) {
|
|
5432
|
-
throw new Error("radio widget v0 no longer supports auto noneOfTheAbove");
|
|
5433
|
-
}
|
|
5434
|
-
return {
|
|
5435
|
-
...rest,
|
|
5436
|
-
hasNoneOfTheAbove: false
|
|
5437
|
-
};
|
|
5438
|
-
}
|
|
5439
|
-
};
|
|
5440
|
-
const defaultWidgetOptions$3 = {
|
|
5441
|
-
choices: [{}, {}, {}, {}],
|
|
5442
|
-
displayCount: null,
|
|
5443
|
-
randomize: false,
|
|
5444
|
-
hasNoneOfTheAbove: false,
|
|
5445
|
-
multipleSelect: false,
|
|
5446
|
-
countChoices: false,
|
|
5447
|
-
deselectEnabled: false
|
|
3715
|
+
defaultWidgetOptions: defaultWidgetOptions$3
|
|
5448
3716
|
};
|
|
5449
3717
|
|
|
5450
3718
|
/**
|
|
@@ -5473,22 +3741,41 @@ function getRadioChoicePublicData(choice) {
|
|
|
5473
3741
|
};
|
|
5474
3742
|
}
|
|
5475
3743
|
|
|
3744
|
+
/**
|
|
3745
|
+
* Shared functionality to determine if numCorrect is used, because:
|
|
3746
|
+
*
|
|
3747
|
+
* 1. numCorrect is conditionally used for rendering pre-scoring
|
|
3748
|
+
* 2. numCorrect also exposes information about answers
|
|
3749
|
+
*
|
|
3750
|
+
* So only include/use numCorrect when we know it's useful.
|
|
3751
|
+
*/
|
|
3752
|
+
function usesNumCorrect(multipleSelect, countChoices, numCorrect) {
|
|
3753
|
+
return multipleSelect && countChoices && numCorrect;
|
|
3754
|
+
}
|
|
3755
|
+
|
|
5476
3756
|
/**
|
|
5477
3757
|
* Given a PerseusRadioWidgetOptions object, return a new object with only
|
|
5478
3758
|
* the public options that should be exposed to the client.
|
|
5479
3759
|
*/
|
|
5480
3760
|
function getRadioPublicWidgetOptions(options) {
|
|
3761
|
+
const {
|
|
3762
|
+
numCorrect,
|
|
3763
|
+
choices,
|
|
3764
|
+
multipleSelect,
|
|
3765
|
+
countChoices
|
|
3766
|
+
} = options;
|
|
5481
3767
|
return {
|
|
5482
3768
|
...options,
|
|
5483
|
-
|
|
3769
|
+
numCorrect: usesNumCorrect(multipleSelect, countChoices, numCorrect) ? numCorrect : undefined,
|
|
3770
|
+
choices: choices.map(getRadioChoicePublicData)
|
|
5484
3771
|
};
|
|
5485
3772
|
}
|
|
5486
3773
|
|
|
5487
3774
|
const radioWidgetLogic = {
|
|
5488
3775
|
name: "radio",
|
|
5489
|
-
version: currentVersion,
|
|
5490
|
-
widgetOptionsUpgrades: widgetOptionsUpgrades,
|
|
5491
|
-
defaultWidgetOptions: defaultWidgetOptions$
|
|
3776
|
+
version: currentVersion$3,
|
|
3777
|
+
widgetOptionsUpgrades: widgetOptionsUpgrades$2,
|
|
3778
|
+
defaultWidgetOptions: defaultWidgetOptions$v,
|
|
5492
3779
|
getPublicWidgetOptions: getRadioPublicWidgetOptions
|
|
5493
3780
|
};
|
|
5494
3781
|
|
|
@@ -5682,7 +3969,7 @@ const upgradeWidgetInfoToLatestVersion = oldWidgetInfo => {
|
|
|
5682
3969
|
// that `type` is non-optional. But we're seeing this in Sentry today so I
|
|
5683
3970
|
// suspect we have legacy data (potentially unpublished) and we should
|
|
5684
3971
|
// figure that out before depending solely on types.
|
|
5685
|
-
if (!
|
|
3972
|
+
if (!___default["default"].isString(type)) {
|
|
5686
3973
|
throw new PerseusError("widget type must be a string, but was: " + type, Errors.Internal);
|
|
5687
3974
|
}
|
|
5688
3975
|
if (!isWidgetRegistered(type)) {
|
|
@@ -5708,14 +3995,14 @@ const upgradeWidgetInfoToLatestVersion = oldWidgetInfo => {
|
|
|
5708
3995
|
// We do a clone here so that it's safe to mutate the input parameter
|
|
5709
3996
|
// in propUpgrades functions (which I will probably accidentally do at
|
|
5710
3997
|
// some point, and we would like to not break when that happens).
|
|
5711
|
-
let newEditorOptions =
|
|
3998
|
+
let newEditorOptions = ___default["default"].clone(oldWidgetInfo.options) || {};
|
|
5712
3999
|
const upgradePropsMap = getWidgetOptionsUpgrades(type);
|
|
5713
4000
|
|
|
5714
4001
|
// Empty props usually mean a newly created widget by the editor,
|
|
5715
4002
|
// and are always considerered up-to-date.
|
|
5716
4003
|
// Mostly, we'd rather not run upgrade functions on props that are
|
|
5717
4004
|
// not complete.
|
|
5718
|
-
if (
|
|
4005
|
+
if (___default["default"].keys(newEditorOptions).length !== 0) {
|
|
5719
4006
|
// We loop through all the versions after the current version of
|
|
5720
4007
|
// the loaded widget, up to and including the latest version of the
|
|
5721
4008
|
// loaded widget, and run the upgrade function to bring our loaded
|
|
@@ -5802,7 +4089,7 @@ function getUpgradedWidgetOptions(oldWidgetOptions) {
|
|
|
5802
4089
|
}
|
|
5803
4090
|
|
|
5804
4091
|
function splitPerseusItem(originalItem) {
|
|
5805
|
-
const item =
|
|
4092
|
+
const item = ___default["default"].clone(originalItem);
|
|
5806
4093
|
const originalWidgets = item.widgets ?? {};
|
|
5807
4094
|
const upgradedWidgets = getUpgradedWidgetOptions(originalWidgets);
|
|
5808
4095
|
const splitWidgets = {};
|
|
@@ -5843,11 +4130,11 @@ const seededRNG = function (seed) {
|
|
|
5843
4130
|
function shuffle(array, randomSeed) {
|
|
5844
4131
|
let ensurePermuted = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
|
|
5845
4132
|
// Always return a copy of the input array
|
|
5846
|
-
const shuffled =
|
|
4133
|
+
const shuffled = ___default["default"].clone(array);
|
|
5847
4134
|
|
|
5848
4135
|
// Handle edge cases (input array is empty or uniform)
|
|
5849
|
-
if (!shuffled.length ||
|
|
5850
|
-
return
|
|
4136
|
+
if (!shuffled.length || ___default["default"].all(shuffled, function (value) {
|
|
4137
|
+
return ___default["default"].isEqual(value, shuffled[0]);
|
|
5851
4138
|
})) {
|
|
5852
4139
|
return shuffled;
|
|
5853
4140
|
}
|
|
@@ -5868,7 +4155,7 @@ function shuffle(array, randomSeed) {
|
|
|
5868
4155
|
// @ts-expect-error - TS2542 - Index signature in type 'readonly T[]' only permits reading.
|
|
5869
4156
|
shuffled[top - 1] = temp;
|
|
5870
4157
|
}
|
|
5871
|
-
} while (ensurePermuted &&
|
|
4158
|
+
} while (ensurePermuted && ___default["default"].isEqual(array, shuffled));
|
|
5872
4159
|
return shuffled;
|
|
5873
4160
|
}
|
|
5874
4161
|
const random = seededRNG(new Date().getTime() & 0xffffffff);
|
|
@@ -5879,7 +4166,6 @@ exports.GrapherUtil = grapherUtil;
|
|
|
5879
4166
|
exports.ItemExtras = ItemExtras;
|
|
5880
4167
|
exports.PerseusError = PerseusError;
|
|
5881
4168
|
exports.PerseusExpressionAnswerFormConsidered = PerseusExpressionAnswerFormConsidered;
|
|
5882
|
-
exports.addLibraryVersionToPerseusDebug = addLibraryVersionToPerseusDebug;
|
|
5883
4169
|
exports.addWidget = addWidget;
|
|
5884
4170
|
exports.approximateDeepEqual = approximateDeepEqual;
|
|
5885
4171
|
exports.approximateEqual = approximateEqual;
|
|
@@ -5887,6 +4173,8 @@ exports.categorizerLogic = categorizerWidgetLogic;
|
|
|
5887
4173
|
exports.csProgramLogic = csProgramWidgetLogic;
|
|
5888
4174
|
exports.deepClone = deepClone;
|
|
5889
4175
|
exports.definitionLogic = definitionWidgetLogic;
|
|
4176
|
+
exports.deriveExtraKeys = deriveExtraKeys;
|
|
4177
|
+
exports.deriveNumCorrect = deriveNumCorrect;
|
|
5890
4178
|
exports.dropdownLogic = dropdownWidgetLogic;
|
|
5891
4179
|
exports.explanationLogic = explanationWidgetLogic;
|
|
5892
4180
|
exports.expressionLogic = expressionWidgetLogic;
|
|
@@ -5955,5 +4243,6 @@ exports.sorterLogic = sorterWidgetLogic;
|
|
|
5955
4243
|
exports.splitPerseusItem = splitPerseusItem;
|
|
5956
4244
|
exports.tableLogic = tableWidgetLogic;
|
|
5957
4245
|
exports.upgradeWidgetInfoToLatestVersion = upgradeWidgetInfoToLatestVersion;
|
|
4246
|
+
exports.usesNumCorrect = usesNumCorrect;
|
|
5958
4247
|
exports.videoLogic = videoWidgetLogic;
|
|
5959
4248
|
//# sourceMappingURL=index.js.map
|