playcademy 0.28.1-beta.4 → 0.28.1-beta.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bucket.js +35 -2
- package/dist/cli.js +36 -3
- package/dist/constants.js +1 -1
- package/dist/db.js +35 -2
- package/dist/index.js +38 -5
- package/dist/runtime/dashboard-runtime/manifest.json +4 -4
- package/dist/runtime/game-runtime/index.js +509 -180
- package/dist/runtime/game-runtime/manifest.json +4 -4
- package/dist/utils.js +38 -5
- package/dist/version.js +1 -1
- package/package.json +2 -2
package/dist/bucket.js
CHANGED
|
@@ -44,7 +44,7 @@ var GAME_API_ROUTES_DIRECTORY = join2(GAME_SERVER_ROOT_DIRECTORY, "api");
|
|
|
44
44
|
// ../better-auth/package.json
|
|
45
45
|
var package_default = {
|
|
46
46
|
name: "@playcademy/better-auth",
|
|
47
|
-
version: "0.0.21-beta.
|
|
47
|
+
version: "0.0.21-beta.6",
|
|
48
48
|
type: "module",
|
|
49
49
|
exports: {
|
|
50
50
|
"./server": {
|
|
@@ -282,11 +282,44 @@ var PLAYCADEMY_SUPPORTED_QTI_INTERACTION_TYPES = [
|
|
|
282
282
|
"text-entry",
|
|
283
283
|
"order",
|
|
284
284
|
"match",
|
|
285
|
-
"hottext"
|
|
285
|
+
"hottext",
|
|
286
|
+
"hotspot",
|
|
287
|
+
"gap-match",
|
|
288
|
+
"graphic-gap-match",
|
|
289
|
+
"select-point",
|
|
290
|
+
"graphic-associate",
|
|
291
|
+
"position-object"
|
|
286
292
|
];
|
|
287
293
|
var PLAYCADEMY_SUPPORTED_QTI_INTERACTION_TYPE_SET = new Set(
|
|
288
294
|
PLAYCADEMY_SUPPORTED_QTI_INTERACTION_TYPES
|
|
289
295
|
);
|
|
296
|
+
var PLAYCADEMY_AUTHORABLE_QTI_INTERACTION_TYPES = [
|
|
297
|
+
"choice",
|
|
298
|
+
"inline-choice",
|
|
299
|
+
"text-entry",
|
|
300
|
+
"order",
|
|
301
|
+
"match",
|
|
302
|
+
"hottext",
|
|
303
|
+
"gap-match",
|
|
304
|
+
"hotspot",
|
|
305
|
+
"graphic-associate",
|
|
306
|
+
"graphic-gap-match"
|
|
307
|
+
];
|
|
308
|
+
var PLAYCADEMY_AUTHORABLE_QTI_INTERACTION_TYPE_SET = new Set(
|
|
309
|
+
PLAYCADEMY_AUTHORABLE_QTI_INTERACTION_TYPES
|
|
310
|
+
);
|
|
311
|
+
var QTI_RASTER_IMAGE_MIME_TYPES = [
|
|
312
|
+
"image/png",
|
|
313
|
+
"image/jpeg",
|
|
314
|
+
// Some browsers and operating systems still report the legacy jpg spelling.
|
|
315
|
+
"image/jpg",
|
|
316
|
+
"image/gif",
|
|
317
|
+
"image/webp",
|
|
318
|
+
"image/bmp"
|
|
319
|
+
];
|
|
320
|
+
var QTI_RASTER_IMAGE_SUBTYPE_PATTERN = QTI_RASTER_IMAGE_MIME_TYPES.map(
|
|
321
|
+
(type) => type.slice("image/".length)
|
|
322
|
+
).join("|");
|
|
290
323
|
var TIMEBACK_DISCREPANCY_QUEUE_WINDOW_VALUES = new Set(TIMEBACK_DISCREPANCY_QUEUE_WINDOWS);
|
|
291
324
|
var TIMEBACK_DISCREPANCY_QUEUE_METRIC_VALUES = new Set(TIMEBACK_DISCREPANCY_QUEUE_METRICS);
|
|
292
325
|
|
package/dist/cli.js
CHANGED
|
@@ -1207,7 +1207,7 @@ var SAMPLE_BUCKET_FILENAME = "bucket.ts";
|
|
|
1207
1207
|
// ../better-auth/package.json
|
|
1208
1208
|
var package_default = {
|
|
1209
1209
|
name: "@playcademy/better-auth",
|
|
1210
|
-
version: "0.0.21-beta.
|
|
1210
|
+
version: "0.0.21-beta.6",
|
|
1211
1211
|
type: "module",
|
|
1212
1212
|
exports: {
|
|
1213
1213
|
"./server": {
|
|
@@ -2123,11 +2123,44 @@ var PLAYCADEMY_SUPPORTED_QTI_INTERACTION_TYPES = [
|
|
|
2123
2123
|
"text-entry",
|
|
2124
2124
|
"order",
|
|
2125
2125
|
"match",
|
|
2126
|
-
"hottext"
|
|
2126
|
+
"hottext",
|
|
2127
|
+
"hotspot",
|
|
2128
|
+
"gap-match",
|
|
2129
|
+
"graphic-gap-match",
|
|
2130
|
+
"select-point",
|
|
2131
|
+
"graphic-associate",
|
|
2132
|
+
"position-object"
|
|
2127
2133
|
];
|
|
2128
2134
|
var PLAYCADEMY_SUPPORTED_QTI_INTERACTION_TYPE_SET = new Set(
|
|
2129
2135
|
PLAYCADEMY_SUPPORTED_QTI_INTERACTION_TYPES
|
|
2130
2136
|
);
|
|
2137
|
+
var PLAYCADEMY_AUTHORABLE_QTI_INTERACTION_TYPES = [
|
|
2138
|
+
"choice",
|
|
2139
|
+
"inline-choice",
|
|
2140
|
+
"text-entry",
|
|
2141
|
+
"order",
|
|
2142
|
+
"match",
|
|
2143
|
+
"hottext",
|
|
2144
|
+
"gap-match",
|
|
2145
|
+
"hotspot",
|
|
2146
|
+
"graphic-associate",
|
|
2147
|
+
"graphic-gap-match"
|
|
2148
|
+
];
|
|
2149
|
+
var PLAYCADEMY_AUTHORABLE_QTI_INTERACTION_TYPE_SET = new Set(
|
|
2150
|
+
PLAYCADEMY_AUTHORABLE_QTI_INTERACTION_TYPES
|
|
2151
|
+
);
|
|
2152
|
+
var QTI_RASTER_IMAGE_MIME_TYPES = [
|
|
2153
|
+
"image/png",
|
|
2154
|
+
"image/jpeg",
|
|
2155
|
+
// Some browsers and operating systems still report the legacy jpg spelling.
|
|
2156
|
+
"image/jpg",
|
|
2157
|
+
"image/gif",
|
|
2158
|
+
"image/webp",
|
|
2159
|
+
"image/bmp"
|
|
2160
|
+
];
|
|
2161
|
+
var QTI_RASTER_IMAGE_SUBTYPE_PATTERN = QTI_RASTER_IMAGE_MIME_TYPES.map(
|
|
2162
|
+
(type) => type.slice("image/".length)
|
|
2163
|
+
).join("|");
|
|
2131
2164
|
var TIMEBACK_DISCREPANCY_QUEUE_WINDOW_VALUES = new Set(TIMEBACK_DISCREPANCY_QUEUE_WINDOWS);
|
|
2132
2165
|
var TIMEBACK_DISCREPANCY_QUEUE_METRIC_VALUES = new Set(TIMEBACK_DISCREPANCY_QUEUE_METRICS);
|
|
2133
2166
|
|
|
@@ -3009,7 +3042,7 @@ import { existsSync as existsSync11, mkdirSync as mkdirSync5, readFileSync as re
|
|
|
3009
3042
|
import { join as join13 } from "node:path";
|
|
3010
3043
|
|
|
3011
3044
|
// src/version.ts
|
|
3012
|
-
var cliVersion = false ? "0.0.0-dev" : "0.28.1-beta.
|
|
3045
|
+
var cliVersion = false ? "0.0.0-dev" : "0.28.1-beta.6";
|
|
3013
3046
|
|
|
3014
3047
|
// src/lib/init/database.ts
|
|
3015
3048
|
var drizzleConfigTemplate = loadTemplateString("database/drizzle-config.ts");
|
package/dist/constants.js
CHANGED
package/dist/db.js
CHANGED
|
@@ -2335,7 +2335,7 @@ var GAME_API_ROUTES_DIRECTORY = join2(GAME_SERVER_ROOT_DIRECTORY, "api");
|
|
|
2335
2335
|
// ../better-auth/package.json
|
|
2336
2336
|
var package_default = {
|
|
2337
2337
|
name: "@playcademy/better-auth",
|
|
2338
|
-
version: "0.0.21-beta.
|
|
2338
|
+
version: "0.0.21-beta.6",
|
|
2339
2339
|
type: "module",
|
|
2340
2340
|
exports: {
|
|
2341
2341
|
"./server": {
|
|
@@ -4209,11 +4209,44 @@ var PLAYCADEMY_SUPPORTED_QTI_INTERACTION_TYPES = [
|
|
|
4209
4209
|
"text-entry",
|
|
4210
4210
|
"order",
|
|
4211
4211
|
"match",
|
|
4212
|
-
"hottext"
|
|
4212
|
+
"hottext",
|
|
4213
|
+
"hotspot",
|
|
4214
|
+
"gap-match",
|
|
4215
|
+
"graphic-gap-match",
|
|
4216
|
+
"select-point",
|
|
4217
|
+
"graphic-associate",
|
|
4218
|
+
"position-object"
|
|
4213
4219
|
];
|
|
4214
4220
|
var PLAYCADEMY_SUPPORTED_QTI_INTERACTION_TYPE_SET = new Set(
|
|
4215
4221
|
PLAYCADEMY_SUPPORTED_QTI_INTERACTION_TYPES
|
|
4216
4222
|
);
|
|
4223
|
+
var PLAYCADEMY_AUTHORABLE_QTI_INTERACTION_TYPES = [
|
|
4224
|
+
"choice",
|
|
4225
|
+
"inline-choice",
|
|
4226
|
+
"text-entry",
|
|
4227
|
+
"order",
|
|
4228
|
+
"match",
|
|
4229
|
+
"hottext",
|
|
4230
|
+
"gap-match",
|
|
4231
|
+
"hotspot",
|
|
4232
|
+
"graphic-associate",
|
|
4233
|
+
"graphic-gap-match"
|
|
4234
|
+
];
|
|
4235
|
+
var PLAYCADEMY_AUTHORABLE_QTI_INTERACTION_TYPE_SET = new Set(
|
|
4236
|
+
PLAYCADEMY_AUTHORABLE_QTI_INTERACTION_TYPES
|
|
4237
|
+
);
|
|
4238
|
+
var QTI_RASTER_IMAGE_MIME_TYPES = [
|
|
4239
|
+
"image/png",
|
|
4240
|
+
"image/jpeg",
|
|
4241
|
+
// Some browsers and operating systems still report the legacy jpg spelling.
|
|
4242
|
+
"image/jpg",
|
|
4243
|
+
"image/gif",
|
|
4244
|
+
"image/webp",
|
|
4245
|
+
"image/bmp"
|
|
4246
|
+
];
|
|
4247
|
+
var QTI_RASTER_IMAGE_SUBTYPE_PATTERN = QTI_RASTER_IMAGE_MIME_TYPES.map(
|
|
4248
|
+
(type) => type.slice("image/".length)
|
|
4249
|
+
).join("|");
|
|
4217
4250
|
var TIMEBACK_DISCREPANCY_QUEUE_WINDOW_VALUES = new Set(TIMEBACK_DISCREPANCY_QUEUE_WINDOWS);
|
|
4218
4251
|
var TIMEBACK_DISCREPANCY_QUEUE_METRIC_VALUES = new Set(TIMEBACK_DISCREPANCY_QUEUE_METRICS);
|
|
4219
4252
|
|
package/dist/index.js
CHANGED
|
@@ -2346,7 +2346,7 @@ var SAMPLE_BUCKET_FILENAME = "bucket.ts";
|
|
|
2346
2346
|
// ../better-auth/package.json
|
|
2347
2347
|
var package_default = {
|
|
2348
2348
|
name: "@playcademy/better-auth",
|
|
2349
|
-
version: "0.0.21-beta.
|
|
2349
|
+
version: "0.0.21-beta.6",
|
|
2350
2350
|
type: "module",
|
|
2351
2351
|
exports: {
|
|
2352
2352
|
"./server": {
|
|
@@ -4959,11 +4959,44 @@ var PLAYCADEMY_SUPPORTED_QTI_INTERACTION_TYPES = [
|
|
|
4959
4959
|
"text-entry",
|
|
4960
4960
|
"order",
|
|
4961
4961
|
"match",
|
|
4962
|
-
"hottext"
|
|
4962
|
+
"hottext",
|
|
4963
|
+
"hotspot",
|
|
4964
|
+
"gap-match",
|
|
4965
|
+
"graphic-gap-match",
|
|
4966
|
+
"select-point",
|
|
4967
|
+
"graphic-associate",
|
|
4968
|
+
"position-object"
|
|
4963
4969
|
];
|
|
4964
4970
|
var PLAYCADEMY_SUPPORTED_QTI_INTERACTION_TYPE_SET = new Set(
|
|
4965
4971
|
PLAYCADEMY_SUPPORTED_QTI_INTERACTION_TYPES
|
|
4966
4972
|
);
|
|
4973
|
+
var PLAYCADEMY_AUTHORABLE_QTI_INTERACTION_TYPES = [
|
|
4974
|
+
"choice",
|
|
4975
|
+
"inline-choice",
|
|
4976
|
+
"text-entry",
|
|
4977
|
+
"order",
|
|
4978
|
+
"match",
|
|
4979
|
+
"hottext",
|
|
4980
|
+
"gap-match",
|
|
4981
|
+
"hotspot",
|
|
4982
|
+
"graphic-associate",
|
|
4983
|
+
"graphic-gap-match"
|
|
4984
|
+
];
|
|
4985
|
+
var PLAYCADEMY_AUTHORABLE_QTI_INTERACTION_TYPE_SET = new Set(
|
|
4986
|
+
PLAYCADEMY_AUTHORABLE_QTI_INTERACTION_TYPES
|
|
4987
|
+
);
|
|
4988
|
+
var QTI_RASTER_IMAGE_MIME_TYPES = [
|
|
4989
|
+
"image/png",
|
|
4990
|
+
"image/jpeg",
|
|
4991
|
+
// Some browsers and operating systems still report the legacy jpg spelling.
|
|
4992
|
+
"image/jpg",
|
|
4993
|
+
"image/gif",
|
|
4994
|
+
"image/webp",
|
|
4995
|
+
"image/bmp"
|
|
4996
|
+
];
|
|
4997
|
+
var QTI_RASTER_IMAGE_SUBTYPE_PATTERN = QTI_RASTER_IMAGE_MIME_TYPES.map(
|
|
4998
|
+
(type) => type.slice("image/".length)
|
|
4999
|
+
).join("|");
|
|
4967
5000
|
var TIMEBACK_DISCREPANCY_QUEUE_WINDOW_VALUES = new Set(TIMEBACK_DISCREPANCY_QUEUE_WINDOWS);
|
|
4968
5001
|
var TIMEBACK_DISCREPANCY_QUEUE_METRIC_VALUES = new Set(TIMEBACK_DISCREPANCY_QUEUE_METRICS);
|
|
4969
5002
|
function formatGradeLabel(grade) {
|
|
@@ -6396,7 +6429,7 @@ import { existsSync as existsSync10, mkdirSync as mkdirSync2, readFileSync as re
|
|
|
6396
6429
|
import { join as join13 } from "node:path";
|
|
6397
6430
|
|
|
6398
6431
|
// src/version.ts
|
|
6399
|
-
var cliVersion = false ? "0.0.0-dev" : "0.28.1-beta.
|
|
6432
|
+
var cliVersion = false ? "0.0.0-dev" : "0.28.1-beta.6";
|
|
6400
6433
|
|
|
6401
6434
|
// src/lib/init/database.ts
|
|
6402
6435
|
var drizzleConfigTemplate = loadTemplateString("database/drizzle-config.ts");
|
|
@@ -17431,14 +17464,14 @@ function isAssessmentResponseValue(value) {
|
|
|
17431
17464
|
return entries.length > 0 && entries.every((entry) => typeof entry === "string" && entry.length > 0 && entry.length <= TIMEBACK_ASSESSMENT_RESPONSE_VALUE_MAX_LENGTH);
|
|
17432
17465
|
}
|
|
17433
17466
|
function isAssessmentRuntimeFixtureBundle(value) {
|
|
17434
|
-
if (!isRecord2(value) || value.version !==
|
|
17467
|
+
if (!isRecord2(value) || value.version !== 3 || typeof value.gameId !== "string" || typeof value.exportedAt !== "string" || !Array.isArray(value.catalogs)) {
|
|
17435
17468
|
return false;
|
|
17436
17469
|
}
|
|
17437
17470
|
return value.catalogs.every((catalog) => {
|
|
17438
17471
|
if (!isRecord2(catalog) || typeof catalog.id !== "string" || typeof catalog.integrationId !== "string" || !isAssessmentPurpose(catalog.purpose) || typeof catalog.subject !== "string" || !Number.isInteger(catalog.grade) || !Array.isArray(catalog.tests)) {
|
|
17439
17472
|
return false;
|
|
17440
17473
|
}
|
|
17441
|
-
return catalog.tests.every((test) => isRecord2(test) && typeof test.id === "string" && typeof test.qtiTestIdentifier === "string" && (test.sortOrder === null || Number.isInteger(test.sortOrder)) && typeof test.updatedAt === "string" && typeof test.live === "boolean" && isRecord2(test.assessment) && typeof test.assessment.identifier === "string" && typeof test.assessment.
|
|
17474
|
+
return catalog.tests.every((test) => isRecord2(test) && typeof test.id === "string" && typeof test.qtiTestIdentifier === "string" && (test.sortOrder === null || Number.isInteger(test.sortOrder)) && typeof test.updatedAt === "string" && typeof test.live === "boolean" && isRecord2(test.assessment) && typeof test.assessment.identifier === "string" && Number.isInteger(test.assessment.contractVersion) && typeof test.assessment.contentRevision === "string" && Array.isArray(test.assessment.items) && isRecord2(test.correctResponses));
|
|
17442
17475
|
});
|
|
17443
17476
|
}
|
|
17444
17477
|
var RuntimeSubjectSchema = external_exports.enum(TIMEBACK_SUBJECTS);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
|
-
"cliVersion": "0.28.1-beta.
|
|
3
|
-
"sdkVersion": "0.16.1-beta.
|
|
4
|
-
"runtimeBuildId": "
|
|
5
|
-
"inputFingerprint": "
|
|
2
|
+
"cliVersion": "0.28.1-beta.6",
|
|
3
|
+
"sdkVersion": "0.16.1-beta.6",
|
|
4
|
+
"runtimeBuildId": "0a295619c459",
|
|
5
|
+
"inputFingerprint": "0a295619c459fabba64e443c7824867a149bce88a5cfee63d7a97852609a617e",
|
|
6
6
|
"entry": "index.js"
|
|
7
7
|
}
|
|
@@ -367,10 +367,33 @@ var init_constants2 = __esm({
|
|
|
367
367
|
});
|
|
368
368
|
|
|
369
369
|
// ../sdk/src/messaging.ts
|
|
370
|
-
|
|
370
|
+
function isFromParentWindow(event) {
|
|
371
|
+
return globalThis.window.parent !== globalThis.window && event.source === globalThis.window.parent;
|
|
372
|
+
}
|
|
373
|
+
var MESSAGE_DIRECTION, PlaycademyMessaging, messaging;
|
|
371
374
|
var init_messaging = __esm({
|
|
372
375
|
"../sdk/src/messaging.ts"() {
|
|
373
376
|
"use strict";
|
|
377
|
+
MESSAGE_DIRECTION = {
|
|
378
|
+
["PLAYCADEMY_INIT" /* INIT */]: "launcher-to-game",
|
|
379
|
+
["PLAYCADEMY_TOKEN_REFRESH" /* TOKEN_REFRESH */]: "launcher-to-game",
|
|
380
|
+
["PLAYCADEMY_PAUSE" /* PAUSE */]: "launcher-to-game",
|
|
381
|
+
["PLAYCADEMY_RESUME" /* RESUME */]: "launcher-to-game",
|
|
382
|
+
["PLAYCADEMY_FORCE_EXIT" /* FORCE_EXIT */]: "launcher-to-game",
|
|
383
|
+
["PLAYCADEMY_OVERLAY" /* OVERLAY */]: "launcher-to-game",
|
|
384
|
+
["PLAYCADEMY_READY" /* READY */]: "game-to-launcher",
|
|
385
|
+
["PLAYCADEMY_INIT_ERROR" /* INIT_ERROR */]: "game-to-launcher",
|
|
386
|
+
["PLAYCADEMY_EXIT" /* EXIT */]: "game-to-launcher",
|
|
387
|
+
["PLAYCADEMY_TELEMETRY" /* TELEMETRY */]: "game-to-launcher",
|
|
388
|
+
["PLAYCADEMY_KEY_EVENT" /* KEY_EVENT */]: "game-to-launcher",
|
|
389
|
+
["PLAYCADEMY_DEMO_END" /* DEMO_END */]: "game-to-launcher",
|
|
390
|
+
["PLAYCADEMY_TIMEBACK_HEARTBEAT_RELAY" /* TIMEBACK_HEARTBEAT_RELAY */]: "game-to-launcher",
|
|
391
|
+
["PLAYCADEMY_TIMEBACK_ACTIVITY_START" /* TIMEBACK_ACTIVITY_START */]: "game-to-launcher",
|
|
392
|
+
["PLAYCADEMY_TIMEBACK_ACTIVITY_END" /* TIMEBACK_ACTIVITY_END */]: "game-to-launcher",
|
|
393
|
+
["PLAYCADEMY_CHECKPOINT" /* CHECKPOINT */]: "game-to-launcher",
|
|
394
|
+
["PLAYCADEMY_AUTH_STATE_CHANGE" /* AUTH_STATE_CHANGE */]: "unscoped",
|
|
395
|
+
["PLAYCADEMY_AUTH_CALLBACK" /* AUTH_CALLBACK */]: "unscoped"
|
|
396
|
+
};
|
|
374
397
|
PlaycademyMessaging = class {
|
|
375
398
|
/**
|
|
376
399
|
* Internal storage for message listeners.
|
|
@@ -480,12 +503,17 @@ var init_messaging = __esm({
|
|
|
480
503
|
* })
|
|
481
504
|
* ```
|
|
482
505
|
*/
|
|
483
|
-
listen(type, handler) {
|
|
506
|
+
listen(type, handler, options) {
|
|
507
|
+
const gateToParent = options?.fromParent ?? MESSAGE_DIRECTION[type] === "launcher-to-game";
|
|
484
508
|
function postMessageListener(event) {
|
|
485
509
|
const messageEvent = event;
|
|
486
|
-
if (messageEvent.data?.type
|
|
487
|
-
|
|
510
|
+
if (messageEvent.data?.type !== type) {
|
|
511
|
+
return;
|
|
512
|
+
}
|
|
513
|
+
if (gateToParent && !isFromParentWindow(messageEvent)) {
|
|
514
|
+
return;
|
|
488
515
|
}
|
|
516
|
+
handler(messageEvent.data.payload || messageEvent.data);
|
|
489
517
|
}
|
|
490
518
|
function customEventListener(event) {
|
|
491
519
|
handler(event.detail);
|
|
@@ -599,23 +627,7 @@ var init_messaging = __esm({
|
|
|
599
627
|
*/
|
|
600
628
|
getMessagingContext(eventType) {
|
|
601
629
|
const isIframe = typeof globalThis.window !== "undefined" && globalThis.self !== window.top;
|
|
602
|
-
const
|
|
603
|
-
"PLAYCADEMY_READY" /* READY */,
|
|
604
|
-
// "I'm loaded and ready"
|
|
605
|
-
"PLAYCADEMY_INIT_ERROR" /* INIT_ERROR */,
|
|
606
|
-
// "SDK init failed"
|
|
607
|
-
"PLAYCADEMY_EXIT" /* EXIT */,
|
|
608
|
-
// "Please close me"
|
|
609
|
-
"PLAYCADEMY_TELEMETRY" /* TELEMETRY */,
|
|
610
|
-
// "Here's my performance data"
|
|
611
|
-
"PLAYCADEMY_KEY_EVENT" /* KEY_EVENT */,
|
|
612
|
-
// Key events like Escape pressed inside game
|
|
613
|
-
"PLAYCADEMY_DEMO_END" /* DEMO_END */,
|
|
614
|
-
// "The demo boundary has been reached"
|
|
615
|
-
"PLAYCADEMY_TIMEBACK_HEARTBEAT_RELAY" /* TIMEBACK_HEARTBEAT_RELAY */
|
|
616
|
-
// "Relay my latest TimeBack heartbeat"
|
|
617
|
-
];
|
|
618
|
-
const shouldUsePostMessage = isIframe && iframeToParentEvents.includes(eventType);
|
|
630
|
+
const shouldUsePostMessage = isIframe && MESSAGE_DIRECTION[eventType] === "game-to-launcher";
|
|
619
631
|
return {
|
|
620
632
|
shouldUsePostMessage,
|
|
621
633
|
target: shouldUsePostMessage ? window.parent : void 0,
|
|
@@ -731,11 +743,29 @@ var init_messaging = __esm({
|
|
|
731
743
|
}
|
|
732
744
|
});
|
|
733
745
|
|
|
746
|
+
// ../sdk/src/core/launch/handshake.ts
|
|
747
|
+
var init_handshake = __esm({
|
|
748
|
+
"../sdk/src/core/launch/handshake.ts"() {
|
|
749
|
+
"use strict";
|
|
750
|
+
init_messaging();
|
|
751
|
+
}
|
|
752
|
+
});
|
|
753
|
+
|
|
754
|
+
// ../sdk/src/core/launch/context.ts
|
|
755
|
+
var init_context = __esm({
|
|
756
|
+
"../sdk/src/core/launch/context.ts"() {
|
|
757
|
+
"use strict";
|
|
758
|
+
init_messaging();
|
|
759
|
+
init_handshake();
|
|
760
|
+
}
|
|
761
|
+
});
|
|
762
|
+
|
|
734
763
|
// ../sdk/src/core/static/init.ts
|
|
735
764
|
var init_init = __esm({
|
|
736
765
|
"../sdk/src/core/static/init.ts"() {
|
|
737
766
|
"use strict";
|
|
738
767
|
init_messaging();
|
|
768
|
+
init_context();
|
|
739
769
|
}
|
|
740
770
|
});
|
|
741
771
|
|
|
@@ -1034,6 +1064,101 @@ var init_demo = __esm({
|
|
|
1034
1064
|
}
|
|
1035
1065
|
});
|
|
1036
1066
|
|
|
1067
|
+
// ../utils/src/error.ts
|
|
1068
|
+
var init_error = __esm({
|
|
1069
|
+
"../utils/src/error.ts"() {
|
|
1070
|
+
}
|
|
1071
|
+
});
|
|
1072
|
+
|
|
1073
|
+
// ../sdk/src/core/launch/exclusivity.ts
|
|
1074
|
+
var init_exclusivity = __esm({
|
|
1075
|
+
"../sdk/src/core/launch/exclusivity.ts"() {
|
|
1076
|
+
"use strict";
|
|
1077
|
+
}
|
|
1078
|
+
});
|
|
1079
|
+
|
|
1080
|
+
// ../sdk/src/core/launch/guards.ts
|
|
1081
|
+
var init_guards2 = __esm({
|
|
1082
|
+
"../sdk/src/core/launch/guards.ts"() {
|
|
1083
|
+
"use strict";
|
|
1084
|
+
init_guards();
|
|
1085
|
+
}
|
|
1086
|
+
});
|
|
1087
|
+
|
|
1088
|
+
// ../sdk/src/core/launch/resume-store.ts
|
|
1089
|
+
var init_resume_store = __esm({
|
|
1090
|
+
"../sdk/src/core/launch/resume-store.ts"() {
|
|
1091
|
+
"use strict";
|
|
1092
|
+
init_error();
|
|
1093
|
+
}
|
|
1094
|
+
});
|
|
1095
|
+
|
|
1096
|
+
// ../sdk/src/core/launch/session.ts
|
|
1097
|
+
var init_session = __esm({
|
|
1098
|
+
"../sdk/src/core/launch/session.ts"() {
|
|
1099
|
+
"use strict";
|
|
1100
|
+
init_error();
|
|
1101
|
+
init_messaging();
|
|
1102
|
+
init_errors();
|
|
1103
|
+
init_handshake();
|
|
1104
|
+
}
|
|
1105
|
+
});
|
|
1106
|
+
|
|
1107
|
+
// ../utils/src/uuid.ts
|
|
1108
|
+
function isValidUUID(value) {
|
|
1109
|
+
if (!value || typeof value !== "string") {
|
|
1110
|
+
return false;
|
|
1111
|
+
}
|
|
1112
|
+
return UUID_REGEX.test(value);
|
|
1113
|
+
}
|
|
1114
|
+
var UUID_REGEX;
|
|
1115
|
+
var init_uuid = __esm({
|
|
1116
|
+
"../utils/src/uuid.ts"() {
|
|
1117
|
+
UUID_REGEX = /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/;
|
|
1118
|
+
}
|
|
1119
|
+
});
|
|
1120
|
+
|
|
1121
|
+
// ../sdk/src/core/timeback/keepalive.ts
|
|
1122
|
+
var init_keepalive = __esm({
|
|
1123
|
+
"../sdk/src/core/timeback/keepalive.ts"() {
|
|
1124
|
+
"use strict";
|
|
1125
|
+
init_src();
|
|
1126
|
+
}
|
|
1127
|
+
});
|
|
1128
|
+
|
|
1129
|
+
// ../sdk/src/core/timeback/activity-tracker.ts
|
|
1130
|
+
var DEFAULT_PAUSED_HEARTBEAT_TIMEOUT_MS, DEFAULT_INACTIVITY_TIMEOUT_MS;
|
|
1131
|
+
var init_activity_tracker = __esm({
|
|
1132
|
+
"../sdk/src/core/timeback/activity-tracker.ts"() {
|
|
1133
|
+
"use strict";
|
|
1134
|
+
init_src();
|
|
1135
|
+
init_uuid();
|
|
1136
|
+
init_messaging();
|
|
1137
|
+
init_errors();
|
|
1138
|
+
init_exclusivity();
|
|
1139
|
+
init_keepalive();
|
|
1140
|
+
DEFAULT_PAUSED_HEARTBEAT_TIMEOUT_MS = 10 * 60 * 1e3;
|
|
1141
|
+
DEFAULT_INACTIVITY_TIMEOUT_MS = 10 * 60 * 1e3;
|
|
1142
|
+
}
|
|
1143
|
+
});
|
|
1144
|
+
|
|
1145
|
+
// ../sdk/src/namespaces/game/embed.ts
|
|
1146
|
+
var init_embed = __esm({
|
|
1147
|
+
"../sdk/src/namespaces/game/embed.ts"() {
|
|
1148
|
+
"use strict";
|
|
1149
|
+
init_src();
|
|
1150
|
+
init_error();
|
|
1151
|
+
init_assert();
|
|
1152
|
+
init_errors();
|
|
1153
|
+
init_exclusivity();
|
|
1154
|
+
init_guards2();
|
|
1155
|
+
init_resume_store();
|
|
1156
|
+
init_session();
|
|
1157
|
+
init_activity_tracker();
|
|
1158
|
+
init_keepalive();
|
|
1159
|
+
}
|
|
1160
|
+
});
|
|
1161
|
+
|
|
1037
1162
|
// ../sdk/src/core/auth/utils.ts
|
|
1038
1163
|
var init_utils = __esm({
|
|
1039
1164
|
"../sdk/src/core/auth/utils.ts"() {
|
|
@@ -1081,6 +1206,7 @@ var init_login2 = __esm({
|
|
|
1081
1206
|
var init_identity2 = __esm({
|
|
1082
1207
|
"../sdk/src/namespaces/game/identity.ts"() {
|
|
1083
1208
|
"use strict";
|
|
1209
|
+
init_assert();
|
|
1084
1210
|
init_login2();
|
|
1085
1211
|
init_errors();
|
|
1086
1212
|
}
|
|
@@ -1098,6 +1224,7 @@ var init_runtime = __esm({
|
|
|
1098
1224
|
var init_scores = __esm({
|
|
1099
1225
|
"../sdk/src/namespaces/game/scores.ts"() {
|
|
1100
1226
|
"use strict";
|
|
1227
|
+
init_assert();
|
|
1101
1228
|
}
|
|
1102
1229
|
});
|
|
1103
1230
|
|
|
@@ -1108,33 +1235,6 @@ var init_ttl_cache = __esm({
|
|
|
1108
1235
|
}
|
|
1109
1236
|
});
|
|
1110
1237
|
|
|
1111
|
-
// ../utils/src/uuid.ts
|
|
1112
|
-
function isValidUUID(value) {
|
|
1113
|
-
if (!value || typeof value !== "string") {
|
|
1114
|
-
return false;
|
|
1115
|
-
}
|
|
1116
|
-
return UUID_REGEX.test(value);
|
|
1117
|
-
}
|
|
1118
|
-
var UUID_REGEX;
|
|
1119
|
-
var init_uuid = __esm({
|
|
1120
|
-
"../utils/src/uuid.ts"() {
|
|
1121
|
-
UUID_REGEX = /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/;
|
|
1122
|
-
}
|
|
1123
|
-
});
|
|
1124
|
-
|
|
1125
|
-
// ../sdk/src/core/timeback/activity-tracker.ts
|
|
1126
|
-
var DEFAULT_PAUSED_HEARTBEAT_TIMEOUT_MS, DEFAULT_INACTIVITY_TIMEOUT_MS;
|
|
1127
|
-
var init_activity_tracker = __esm({
|
|
1128
|
-
"../sdk/src/core/timeback/activity-tracker.ts"() {
|
|
1129
|
-
"use strict";
|
|
1130
|
-
init_src();
|
|
1131
|
-
init_uuid();
|
|
1132
|
-
init_messaging();
|
|
1133
|
-
DEFAULT_PAUSED_HEARTBEAT_TIMEOUT_MS = 10 * 60 * 1e3;
|
|
1134
|
-
DEFAULT_INACTIVITY_TIMEOUT_MS = 10 * 60 * 1e3;
|
|
1135
|
-
}
|
|
1136
|
-
});
|
|
1137
|
-
|
|
1138
1238
|
// ../sdk/src/core/timeback/user.ts
|
|
1139
1239
|
var init_user = __esm({
|
|
1140
1240
|
"../sdk/src/core/timeback/user.ts"() {
|
|
@@ -1161,6 +1261,7 @@ var init_timeback2 = __esm({
|
|
|
1161
1261
|
init_src();
|
|
1162
1262
|
init_assert();
|
|
1163
1263
|
init_guards();
|
|
1264
|
+
init_exclusivity();
|
|
1164
1265
|
init_engine();
|
|
1165
1266
|
ASSESSMENTS_ROUTE = TIMEBACK_ROUTES.ASSESSMENTS;
|
|
1166
1267
|
}
|
|
@@ -1180,6 +1281,7 @@ var init_game2 = __esm({
|
|
|
1180
1281
|
"use strict";
|
|
1181
1282
|
init_backend();
|
|
1182
1283
|
init_demo();
|
|
1284
|
+
init_embed();
|
|
1183
1285
|
init_identity2();
|
|
1184
1286
|
init_runtime();
|
|
1185
1287
|
init_scores();
|
|
@@ -1202,6 +1304,14 @@ var init_strategies = __esm({
|
|
|
1202
1304
|
}
|
|
1203
1305
|
});
|
|
1204
1306
|
|
|
1307
|
+
// ../sdk/src/core/launch/checkpoint.ts
|
|
1308
|
+
var init_checkpoint = __esm({
|
|
1309
|
+
"../sdk/src/core/launch/checkpoint.ts"() {
|
|
1310
|
+
"use strict";
|
|
1311
|
+
init_messaging();
|
|
1312
|
+
}
|
|
1313
|
+
});
|
|
1314
|
+
|
|
1205
1315
|
// ../sdk/src/core/transport/retry.ts
|
|
1206
1316
|
var init_retry = __esm({
|
|
1207
1317
|
"../sdk/src/core/transport/retry.ts"() {
|
|
@@ -1236,6 +1346,7 @@ var init_base = __esm({
|
|
|
1236
1346
|
init_strategies();
|
|
1237
1347
|
init_utils();
|
|
1238
1348
|
init_errors();
|
|
1349
|
+
init_checkpoint();
|
|
1239
1350
|
init_transport();
|
|
1240
1351
|
init_users();
|
|
1241
1352
|
init_version();
|
|
@@ -1262,6 +1373,93 @@ var init_src3 = __esm({
|
|
|
1262
1373
|
}
|
|
1263
1374
|
});
|
|
1264
1375
|
|
|
1376
|
+
// ../utils/src/timeback.ts
|
|
1377
|
+
function withinQtiCapacity(capacities, usage, identifier) {
|
|
1378
|
+
const used = (usage.get(identifier) ?? 0) + 1;
|
|
1379
|
+
const capacity = capacities.get(identifier) ?? 0;
|
|
1380
|
+
usage.set(identifier, used);
|
|
1381
|
+
return capacity === 0 || used <= capacity;
|
|
1382
|
+
}
|
|
1383
|
+
function formatGradeLabel(grade) {
|
|
1384
|
+
if (grade === null || grade === void 0) {
|
|
1385
|
+
return "N/A";
|
|
1386
|
+
}
|
|
1387
|
+
switch (grade) {
|
|
1388
|
+
case -1: {
|
|
1389
|
+
return "Pre-K";
|
|
1390
|
+
}
|
|
1391
|
+
case 0: {
|
|
1392
|
+
return "Kindergarten";
|
|
1393
|
+
}
|
|
1394
|
+
case 13: {
|
|
1395
|
+
return "AP";
|
|
1396
|
+
}
|
|
1397
|
+
default: {
|
|
1398
|
+
return `Grade ${grade}`;
|
|
1399
|
+
}
|
|
1400
|
+
}
|
|
1401
|
+
}
|
|
1402
|
+
var TIMEBACK_DISCREPANCY_QUEUE_WINDOWS, TIMEBACK_DISCREPANCY_QUEUE_METRICS, PLAYCADEMY_SUPPORTED_QTI_INTERACTION_TYPES, PLAYCADEMY_SUPPORTED_QTI_INTERACTION_TYPE_SET, PLAYCADEMY_AUTHORABLE_QTI_INTERACTION_TYPES, PLAYCADEMY_AUTHORABLE_QTI_INTERACTION_TYPE_SET, QTI_RASTER_IMAGE_MIME_TYPES, QTI_RASTER_IMAGE_SUBTYPE_PATTERN, TIMEBACK_DISCREPANCY_QUEUE_WINDOW_VALUES, TIMEBACK_DISCREPANCY_QUEUE_METRIC_VALUES;
|
|
1403
|
+
var init_timeback3 = __esm({
|
|
1404
|
+
"../utils/src/timeback.ts"() {
|
|
1405
|
+
TIMEBACK_DISCREPANCY_QUEUE_WINDOWS = [
|
|
1406
|
+
"today",
|
|
1407
|
+
"yesterday",
|
|
1408
|
+
"this-week",
|
|
1409
|
+
"last-week",
|
|
1410
|
+
"all",
|
|
1411
|
+
"custom"
|
|
1412
|
+
];
|
|
1413
|
+
TIMEBACK_DISCREPANCY_QUEUE_METRICS = ["xp", "mastery", "time", "score"];
|
|
1414
|
+
PLAYCADEMY_SUPPORTED_QTI_INTERACTION_TYPES = [
|
|
1415
|
+
"choice",
|
|
1416
|
+
"inline-choice",
|
|
1417
|
+
"text-entry",
|
|
1418
|
+
"order",
|
|
1419
|
+
"match",
|
|
1420
|
+
"hottext",
|
|
1421
|
+
"hotspot",
|
|
1422
|
+
"gap-match",
|
|
1423
|
+
"graphic-gap-match",
|
|
1424
|
+
"select-point",
|
|
1425
|
+
"graphic-associate",
|
|
1426
|
+
"position-object"
|
|
1427
|
+
];
|
|
1428
|
+
PLAYCADEMY_SUPPORTED_QTI_INTERACTION_TYPE_SET = new Set(
|
|
1429
|
+
PLAYCADEMY_SUPPORTED_QTI_INTERACTION_TYPES
|
|
1430
|
+
);
|
|
1431
|
+
PLAYCADEMY_AUTHORABLE_QTI_INTERACTION_TYPES = [
|
|
1432
|
+
"choice",
|
|
1433
|
+
"inline-choice",
|
|
1434
|
+
"text-entry",
|
|
1435
|
+
"order",
|
|
1436
|
+
"match",
|
|
1437
|
+
"hottext",
|
|
1438
|
+
"gap-match",
|
|
1439
|
+
"hotspot",
|
|
1440
|
+
"graphic-associate",
|
|
1441
|
+
"graphic-gap-match"
|
|
1442
|
+
];
|
|
1443
|
+
PLAYCADEMY_AUTHORABLE_QTI_INTERACTION_TYPE_SET = new Set(
|
|
1444
|
+
PLAYCADEMY_AUTHORABLE_QTI_INTERACTION_TYPES
|
|
1445
|
+
);
|
|
1446
|
+
QTI_RASTER_IMAGE_MIME_TYPES = [
|
|
1447
|
+
"image/png",
|
|
1448
|
+
"image/jpeg",
|
|
1449
|
+
// Some browsers and operating systems still report the legacy jpg spelling.
|
|
1450
|
+
"image/jpg",
|
|
1451
|
+
"image/gif",
|
|
1452
|
+
"image/webp",
|
|
1453
|
+
"image/bmp"
|
|
1454
|
+
];
|
|
1455
|
+
QTI_RASTER_IMAGE_SUBTYPE_PATTERN = QTI_RASTER_IMAGE_MIME_TYPES.map(
|
|
1456
|
+
(type) => type.slice("image/".length)
|
|
1457
|
+
).join("|");
|
|
1458
|
+
TIMEBACK_DISCREPANCY_QUEUE_WINDOW_VALUES = new Set(TIMEBACK_DISCREPANCY_QUEUE_WINDOWS);
|
|
1459
|
+
TIMEBACK_DISCREPANCY_QUEUE_METRIC_VALUES = new Set(TIMEBACK_DISCREPANCY_QUEUE_METRICS);
|
|
1460
|
+
}
|
|
1461
|
+
});
|
|
1462
|
+
|
|
1265
1463
|
// ../utils/src/fns.ts
|
|
1266
1464
|
function isRecord(value) {
|
|
1267
1465
|
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
@@ -1693,15 +1891,15 @@ var init_parseUtil = __esm({
|
|
|
1693
1891
|
message: issueData.message
|
|
1694
1892
|
};
|
|
1695
1893
|
}
|
|
1696
|
-
let
|
|
1894
|
+
let errorMessage2 = "";
|
|
1697
1895
|
const maps = errorMaps.filter((m) => !!m).slice().reverse();
|
|
1698
1896
|
for (const map of maps) {
|
|
1699
|
-
|
|
1897
|
+
errorMessage2 = map(fullIssue, { data, defaultError: errorMessage2 }).message;
|
|
1700
1898
|
}
|
|
1701
1899
|
return {
|
|
1702
1900
|
...issueData,
|
|
1703
1901
|
path: fullPath,
|
|
1704
|
-
message:
|
|
1902
|
+
message: errorMessage2
|
|
1705
1903
|
};
|
|
1706
1904
|
};
|
|
1707
1905
|
EMPTY_PATH = [];
|
|
@@ -5541,27 +5739,23 @@ function presentationChoices(choices, attemptId, itemIdentifier, domain) {
|
|
|
5541
5739
|
}
|
|
5542
5740
|
function assessmentPresentationForAttempt(assessment, attemptId) {
|
|
5543
5741
|
const items = assessment.items.map((item) => {
|
|
5544
|
-
const
|
|
5545
|
-
|
|
5546
|
-
|
|
5547
|
-
...item,
|
|
5548
|
-
interaction: {
|
|
5742
|
+
const interactions = item.interactions.map((interaction) => {
|
|
5743
|
+
if (interaction.type === "order" && interaction.shuffle) {
|
|
5744
|
+
return {
|
|
5549
5745
|
...interaction,
|
|
5550
|
-
choices: presentationChoices(interaction.choices, attemptId, item.identifier,
|
|
5551
|
-
}
|
|
5552
|
-
}
|
|
5553
|
-
|
|
5554
|
-
|
|
5555
|
-
return {
|
|
5556
|
-
...item,
|
|
5557
|
-
interaction: {
|
|
5746
|
+
choices: presentationChoices(interaction.choices, attemptId, item.identifier, `order\0${interaction.responseIdentifier}`)
|
|
5747
|
+
};
|
|
5748
|
+
}
|
|
5749
|
+
if (interaction.type === "match" && interaction.shuffle) {
|
|
5750
|
+
return {
|
|
5558
5751
|
...interaction,
|
|
5559
|
-
sourceChoices: presentationChoices(interaction.sourceChoices, attemptId, item.identifier,
|
|
5560
|
-
targetChoices: presentationChoices(interaction.targetChoices, attemptId, item.identifier,
|
|
5561
|
-
}
|
|
5562
|
-
}
|
|
5563
|
-
|
|
5564
|
-
|
|
5752
|
+
sourceChoices: presentationChoices(interaction.sourceChoices, attemptId, item.identifier, `match-source\0${interaction.responseIdentifier}`),
|
|
5753
|
+
targetChoices: presentationChoices(interaction.targetChoices, attemptId, item.identifier, `match-target\0${interaction.responseIdentifier}`)
|
|
5754
|
+
};
|
|
5755
|
+
}
|
|
5756
|
+
return interaction;
|
|
5757
|
+
});
|
|
5758
|
+
return { ...item, interactions };
|
|
5565
5759
|
});
|
|
5566
5760
|
return { ...assessment, items };
|
|
5567
5761
|
}
|
|
@@ -5578,7 +5772,14 @@ function isAssessmentResponseValue(value) {
|
|
|
5578
5772
|
function applyAssessmentResponseUpdate(current, update) {
|
|
5579
5773
|
const next = structuredClone(current);
|
|
5580
5774
|
for (const [questionId, questionUpdate] of Object.entries(update)) {
|
|
5581
|
-
const questionResponses =
|
|
5775
|
+
const questionResponses = { ...next[questionId] };
|
|
5776
|
+
for (const [responseId, value] of Object.entries(questionUpdate)) {
|
|
5777
|
+
if (value === null) {
|
|
5778
|
+
delete questionResponses[responseId];
|
|
5779
|
+
} else {
|
|
5780
|
+
questionResponses[responseId] = value;
|
|
5781
|
+
}
|
|
5782
|
+
}
|
|
5582
5783
|
if (Object.keys(questionResponses).length === 0) {
|
|
5583
5784
|
delete next[questionId];
|
|
5584
5785
|
} else {
|
|
@@ -5587,6 +5788,22 @@ function applyAssessmentResponseUpdate(current, update) {
|
|
|
5587
5788
|
}
|
|
5588
5789
|
return next;
|
|
5589
5790
|
}
|
|
5791
|
+
function assessmentResponseUpdateValidationMessage(assessment, update) {
|
|
5792
|
+
const items = new Map(assessment.items.map((item) => [item.identifier, item]));
|
|
5793
|
+
for (const [itemIdentifier, itemUpdate] of Object.entries(update)) {
|
|
5794
|
+
const item = items.get(itemIdentifier);
|
|
5795
|
+
if (!item) {
|
|
5796
|
+
return `Response references unknown assessment item ${itemIdentifier}.`;
|
|
5797
|
+
}
|
|
5798
|
+
const declared = new Set(item.interactions.map((interaction) => interaction.responseIdentifier));
|
|
5799
|
+
for (const responseIdentifier of Object.keys(itemUpdate)) {
|
|
5800
|
+
if (!declared.has(responseIdentifier)) {
|
|
5801
|
+
return `Response for ${itemIdentifier} uses unknown identifier ${responseIdentifier}.`;
|
|
5802
|
+
}
|
|
5803
|
+
}
|
|
5804
|
+
}
|
|
5805
|
+
return null;
|
|
5806
|
+
}
|
|
5590
5807
|
function responseValues(value) {
|
|
5591
5808
|
return Array.isArray(value) ? value : [value];
|
|
5592
5809
|
}
|
|
@@ -5597,49 +5814,165 @@ function assessmentResponseValidationMessage(assessment, responses) {
|
|
|
5597
5814
|
if (!item) {
|
|
5598
5815
|
return `Response references unknown assessment item ${itemIdentifier}.`;
|
|
5599
5816
|
}
|
|
5817
|
+
const interactions = new Map(item.interactions.map((interaction) => [interaction.responseIdentifier, interaction]));
|
|
5600
5818
|
const entries = Object.entries(itemResponses);
|
|
5601
|
-
if (entries.length
|
|
5602
|
-
return `Response for ${itemIdentifier}
|
|
5603
|
-
}
|
|
5604
|
-
const responseValue
|
|
5605
|
-
|
|
5606
|
-
|
|
5607
|
-
|
|
5608
|
-
|
|
5609
|
-
|
|
5610
|
-
|
|
5611
|
-
|
|
5612
|
-
|
|
5613
|
-
|
|
5614
|
-
|
|
5819
|
+
if (entries.length === 0) {
|
|
5820
|
+
return `Response for ${itemIdentifier} is empty or invalid.`;
|
|
5821
|
+
}
|
|
5822
|
+
for (const [responseIdentifier, responseValue] of entries) {
|
|
5823
|
+
const interaction = interactions.get(responseIdentifier);
|
|
5824
|
+
if (!interaction) {
|
|
5825
|
+
return `Response for ${itemIdentifier} uses unknown identifier ${responseIdentifier}.`;
|
|
5826
|
+
}
|
|
5827
|
+
const message2 = interactionResponseValidationMessage(itemIdentifier, interaction, responseValue);
|
|
5828
|
+
if (message2) {
|
|
5829
|
+
return message2;
|
|
5830
|
+
}
|
|
5831
|
+
}
|
|
5832
|
+
}
|
|
5833
|
+
return null;
|
|
5834
|
+
}
|
|
5835
|
+
function directedPairsValidationMessage(itemIdentifier, values, contract) {
|
|
5836
|
+
const sourceCounts = /* @__PURE__ */ new Map();
|
|
5837
|
+
const targetCounts = /* @__PURE__ */ new Map();
|
|
5838
|
+
for (const value of values) {
|
|
5839
|
+
const [source, target, extra] = value.split(" ");
|
|
5840
|
+
if (extra !== void 0 || !source || !target || !contract.sources.has(source) || !contract.targets.has(target)) {
|
|
5841
|
+
return `Response for ${itemIdentifier} contains an invalid association pair.`;
|
|
5842
|
+
}
|
|
5843
|
+
if (!withinQtiCapacity(contract.sources, sourceCounts, source)) {
|
|
5844
|
+
return `Response for ${itemIdentifier} uses a token beyond its allowed placements.`;
|
|
5845
|
+
}
|
|
5846
|
+
if (!withinQtiCapacity(contract.targets, targetCounts, target)) {
|
|
5847
|
+
return `Response for ${itemIdentifier} fills a target beyond its capacity.`;
|
|
5848
|
+
}
|
|
5849
|
+
}
|
|
5850
|
+
return null;
|
|
5851
|
+
}
|
|
5852
|
+
function undirectedPairsValidationMessage(itemIdentifier, values, interaction) {
|
|
5853
|
+
const capacities = new Map(interaction.hotspots.map((candidate) => [candidate.identifier, candidate.matchMax ?? 0]));
|
|
5854
|
+
const usage = /* @__PURE__ */ new Map();
|
|
5855
|
+
const pairs = /* @__PURE__ */ new Set();
|
|
5856
|
+
for (const value of values) {
|
|
5857
|
+
const [first, second, extra] = value.split(" ");
|
|
5858
|
+
if (extra !== void 0 || !first || !second || first === second || !capacities.has(first) || !capacities.has(second)) {
|
|
5859
|
+
return `Response for ${itemIdentifier} contains an invalid association pair.`;
|
|
5860
|
+
}
|
|
5861
|
+
const pair = [first, second].toSorted().join(" ");
|
|
5862
|
+
if (pairs.has(pair)) {
|
|
5863
|
+
return `Response for ${itemIdentifier} repeats an association pair.`;
|
|
5864
|
+
}
|
|
5865
|
+
pairs.add(pair);
|
|
5866
|
+
for (const endpoint of [first, second]) {
|
|
5867
|
+
if (!withinQtiCapacity(capacities, usage, endpoint)) {
|
|
5868
|
+
return `Response for ${itemIdentifier} uses a region beyond its allowed associations.`;
|
|
5869
|
+
}
|
|
5870
|
+
}
|
|
5871
|
+
}
|
|
5872
|
+
return null;
|
|
5873
|
+
}
|
|
5874
|
+
function interactionResponseValidationMessage(itemIdentifier, interaction, responseValue) {
|
|
5875
|
+
if (!isAssessmentResponseValue(responseValue)) {
|
|
5876
|
+
return `Response for ${itemIdentifier} is not a usable value: non-empty text, at most ${TIMEBACK_ASSESSMENT_RESPONSE_VALUE_MAX_LENGTH} characters.`;
|
|
5877
|
+
}
|
|
5878
|
+
const values = responseValues(responseValue);
|
|
5879
|
+
let allowed;
|
|
5880
|
+
let minimum = 1;
|
|
5881
|
+
let maximum = 1;
|
|
5882
|
+
if (interaction.type === "hotspot") {
|
|
5883
|
+
allowed = new Set(interaction.hotspots.map((candidate) => candidate.identifier));
|
|
5884
|
+
minimum = interaction.minChoices;
|
|
5885
|
+
maximum = interaction.maxChoices;
|
|
5886
|
+
} else if (interaction.type === "select-point" || interaction.type === "position-object") {
|
|
5887
|
+
if (values.some((value) => !POINT_RESPONSE_PATTERN.test(value))) {
|
|
5888
|
+
return `Response for ${itemIdentifier} contains an invalid point.`;
|
|
5889
|
+
}
|
|
5890
|
+
if (interaction.type === "select-point") {
|
|
5615
5891
|
minimum = interaction.minChoices;
|
|
5616
5892
|
maximum = interaction.maxChoices;
|
|
5617
|
-
} else
|
|
5618
|
-
|
|
5619
|
-
|
|
5620
|
-
|
|
5621
|
-
|
|
5622
|
-
|
|
5623
|
-
|
|
5624
|
-
|
|
5625
|
-
|
|
5626
|
-
|
|
5627
|
-
|
|
5628
|
-
|
|
5629
|
-
|
|
5630
|
-
|
|
5631
|
-
|
|
5632
|
-
|
|
5633
|
-
|
|
5634
|
-
|
|
5635
|
-
|
|
5636
|
-
|
|
5637
|
-
|
|
5638
|
-
|
|
5893
|
+
} else {
|
|
5894
|
+
maximum = interaction.maxPlacements;
|
|
5895
|
+
}
|
|
5896
|
+
} else if (interaction.type === "gap-match" || interaction.type === "graphic-gap-match") {
|
|
5897
|
+
const tokens = interaction.type === "gap-match" ? interaction.gapTexts : interaction.gapImages;
|
|
5898
|
+
const targets = interaction.type === "gap-match" ? new Map(interaction.gaps.map((gap) => [gap, 1])) : new Map(interaction.hotspots.map((candidate) => [
|
|
5899
|
+
candidate.identifier,
|
|
5900
|
+
candidate.matchMax ?? 0
|
|
5901
|
+
]));
|
|
5902
|
+
const message2 = directedPairsValidationMessage(itemIdentifier, values, {
|
|
5903
|
+
sources: new Map(tokens.map((token) => [token.identifier, token.matchMax])),
|
|
5904
|
+
targets
|
|
5905
|
+
});
|
|
5906
|
+
if (message2) {
|
|
5907
|
+
return message2;
|
|
5908
|
+
}
|
|
5909
|
+
maximum = interaction.maxAssociations;
|
|
5910
|
+
} else if (interaction.type === "graphic-associate") {
|
|
5911
|
+
const message2 = undirectedPairsValidationMessage(itemIdentifier, values, interaction);
|
|
5912
|
+
if (message2) {
|
|
5913
|
+
return message2;
|
|
5914
|
+
}
|
|
5915
|
+
maximum = interaction.maxAssociations;
|
|
5916
|
+
} else if (interaction.type === "choice") {
|
|
5917
|
+
allowed = new Set(interaction.choices.map((candidate) => candidate.identifier));
|
|
5918
|
+
minimum = interaction.minChoices;
|
|
5919
|
+
maximum = interaction.maxChoices;
|
|
5920
|
+
} else if (interaction.type === "order") {
|
|
5921
|
+
allowed = new Set(interaction.choices.map((candidate) => candidate.identifier));
|
|
5922
|
+
minimum = interaction.choices.length;
|
|
5923
|
+
maximum = interaction.choices.length;
|
|
5924
|
+
} else if (interaction.type === "inline-choice") {
|
|
5925
|
+
allowed = new Set(interaction.choices.map((candidate) => candidate.identifier));
|
|
5926
|
+
} else if (interaction.type === "match") {
|
|
5927
|
+
const message2 = directedPairsValidationMessage(itemIdentifier, values, {
|
|
5928
|
+
sources: new Map(interaction.sourceChoices.map((candidate) => [candidate.identifier, 0])),
|
|
5929
|
+
targets: new Map(interaction.targetChoices.map((candidate) => [candidate.identifier, 0]))
|
|
5930
|
+
});
|
|
5931
|
+
if (message2) {
|
|
5932
|
+
return message2;
|
|
5639
5933
|
}
|
|
5934
|
+
maximum = interaction.maxAssociations;
|
|
5935
|
+
} else if (interaction.type === "hottext") {
|
|
5936
|
+
allowed = new Set(interaction.segments.flatMap((segment) => segment.selectable && segment.identifier ? [segment.identifier] : []));
|
|
5937
|
+
maximum = interaction.maxChoices;
|
|
5938
|
+
}
|
|
5939
|
+
if (values.length < minimum || maximum !== 0 && values.length > maximum || new Set(values).size !== values.length || allowed && values.some((value) => !allowed.has(value))) {
|
|
5940
|
+
return `Response for ${itemIdentifier} is not valid for its interaction.`;
|
|
5640
5941
|
}
|
|
5641
5942
|
return null;
|
|
5642
5943
|
}
|
|
5944
|
+
function pointInQtiShape(shape, coords, x, y, bounds) {
|
|
5945
|
+
if (shape === "default") {
|
|
5946
|
+
return !bounds || x >= 0 && x <= bounds.width && y >= 0 && y <= bounds.height;
|
|
5947
|
+
}
|
|
5948
|
+
if (shape === "circle") {
|
|
5949
|
+
const [cx, cy, radius] = coords;
|
|
5950
|
+
return coords.length >= 3 && (x - cx) ** 2 + (y - cy) ** 2 <= (radius ?? 0) ** 2;
|
|
5951
|
+
}
|
|
5952
|
+
if (shape === "ellipse") {
|
|
5953
|
+
const [cx, cy, rx, ry] = coords;
|
|
5954
|
+
return coords.length >= 4 && (rx ?? 0) > 0 && (ry ?? 0) > 0 && ((x - cx) / rx) ** 2 + ((y - cy) / ry) ** 2 <= 1;
|
|
5955
|
+
}
|
|
5956
|
+
if (shape === "rect") {
|
|
5957
|
+
const [left, top, right, bottom] = coords;
|
|
5958
|
+
return coords.length >= 4 && x >= Math.min(left, right) && x <= Math.max(left, right) && y >= Math.min(top, bottom) && y <= Math.max(top, bottom);
|
|
5959
|
+
}
|
|
5960
|
+
if (shape !== "poly" || coords.length < 6) {
|
|
5961
|
+
return false;
|
|
5962
|
+
}
|
|
5963
|
+
let inside = false;
|
|
5964
|
+
for (let index = 0, previous = coords.length - 2; index < coords.length; index += 2) {
|
|
5965
|
+
const vertexX = coords[index];
|
|
5966
|
+
const vertexY = coords[index + 1];
|
|
5967
|
+
const previousX = coords[previous];
|
|
5968
|
+
const previousY = coords[previous + 1];
|
|
5969
|
+
if (vertexY > y !== previousY > y && x < (previousX - vertexX) * (y - vertexY) / (previousY - vertexY) + vertexX) {
|
|
5970
|
+
inside = !inside;
|
|
5971
|
+
}
|
|
5972
|
+
previous = index;
|
|
5973
|
+
}
|
|
5974
|
+
return inside;
|
|
5975
|
+
}
|
|
5643
5976
|
function fixtureValuesEqual(left, right) {
|
|
5644
5977
|
if (left === right) {
|
|
5645
5978
|
return true;
|
|
@@ -5669,35 +6002,71 @@ function fixtureResponseCorrect(interaction, response, correct) {
|
|
|
5669
6002
|
}
|
|
5670
6003
|
return response.every((value) => correct.some((candidate) => fixtureValuesEqual(value, candidate))) && correct.every((candidate) => response.some((value) => fixtureValuesEqual(value, candidate)));
|
|
5671
6004
|
}
|
|
6005
|
+
function assessmentPossibleScore(assessment) {
|
|
6006
|
+
return assessment.items.reduce((sum, item) => sum + item.maxScore, 0);
|
|
6007
|
+
}
|
|
6008
|
+
function fixtureItemEarnedScore(correctInteractions, total, maxScore) {
|
|
6009
|
+
return total === 0 ? 0 : correctInteractions / total * maxScore;
|
|
6010
|
+
}
|
|
6011
|
+
function pointsAreaScore(values, areas) {
|
|
6012
|
+
const points = values.map((value) => value.split(" ").map(Number)).filter((point) => point.length === 2 && point.every(Number.isFinite)).toSorted((left, right) => left[0] - right[0] || left[1] - right[1]);
|
|
6013
|
+
const availableCredit = areas.reduce((sum, area) => sum + (area.value ?? 1), 0);
|
|
6014
|
+
if (points.length === 0 || availableCredit <= 0) {
|
|
6015
|
+
return 0;
|
|
6016
|
+
}
|
|
6017
|
+
const usedPoints = /* @__PURE__ */ new Set();
|
|
6018
|
+
let earnedCredit = 0;
|
|
6019
|
+
for (const area of areas) {
|
|
6020
|
+
const matched = points.findIndex((point, index) => !usedPoints.has(index) && pointInQtiShape(area.shape, area.coords, point[0], point[1]));
|
|
6021
|
+
if (matched !== -1) {
|
|
6022
|
+
usedPoints.add(matched);
|
|
6023
|
+
earnedCredit += area.value ?? 1;
|
|
6024
|
+
}
|
|
6025
|
+
}
|
|
6026
|
+
return usedPoints.size === points.length ? earnedCredit / availableCredit : 0;
|
|
6027
|
+
}
|
|
5672
6028
|
function scoreAssessmentFixture(test, responses) {
|
|
5673
|
-
const
|
|
5674
|
-
|
|
5675
|
-
|
|
5676
|
-
const
|
|
5677
|
-
|
|
5678
|
-
|
|
5679
|
-
|
|
5680
|
-
|
|
5681
|
-
|
|
5682
|
-
|
|
6029
|
+
const possible = assessmentPossibleScore(test.assessment);
|
|
6030
|
+
let earned = 0;
|
|
6031
|
+
for (const item of test.assessment.items) {
|
|
6032
|
+
const interactionScores = item.interactions.map((interaction) => {
|
|
6033
|
+
const identifier = interaction.responseIdentifier;
|
|
6034
|
+
const response = responses[item.identifier]?.[identifier];
|
|
6035
|
+
if (response === void 0) {
|
|
6036
|
+
return 0;
|
|
6037
|
+
}
|
|
6038
|
+
const areas = test.responseAreas?.[item.identifier]?.[identifier];
|
|
6039
|
+
if (areas?.length) {
|
|
6040
|
+
return pointsAreaScore(responseValues(response), areas);
|
|
6041
|
+
}
|
|
6042
|
+
const correct = test.correctResponses[item.identifier]?.[identifier];
|
|
6043
|
+
if (correct === void 0) {
|
|
6044
|
+
return 0;
|
|
6045
|
+
}
|
|
6046
|
+
const canonicalize = interaction.type === "graphic-associate" ? (values) => values.map((value) => value.split(" ").toSorted().join(" ")) : (values) => values;
|
|
6047
|
+
return fixtureResponseCorrect(interaction, canonicalize(responseValues(response)), canonicalize(responseValues(correct))) ? 1 : 0;
|
|
6048
|
+
});
|
|
6049
|
+
earned += fixtureItemEarnedScore(interactionScores.reduce((sum, score) => sum + score, 0), interactionScores.length, item.maxScore);
|
|
6050
|
+
}
|
|
5683
6051
|
return { earned, possible, normalized: possible === 0 ? 0 : earned / possible };
|
|
5684
6052
|
}
|
|
5685
6053
|
function isAssessmentRuntimeFixtureBundle(value) {
|
|
5686
|
-
if (!isRecord(value) || value.version !==
|
|
6054
|
+
if (!isRecord(value) || value.version !== 3 || typeof value.gameId !== "string" || typeof value.exportedAt !== "string" || !Array.isArray(value.catalogs)) {
|
|
5687
6055
|
return false;
|
|
5688
6056
|
}
|
|
5689
6057
|
return value.catalogs.every((catalog) => {
|
|
5690
6058
|
if (!isRecord(catalog) || typeof catalog.id !== "string" || typeof catalog.integrationId !== "string" || !isAssessmentPurpose2(catalog.purpose) || typeof catalog.subject !== "string" || !Number.isInteger(catalog.grade) || !Array.isArray(catalog.tests)) {
|
|
5691
6059
|
return false;
|
|
5692
6060
|
}
|
|
5693
|
-
return catalog.tests.every((test) => isRecord(test) && typeof test.id === "string" && typeof test.qtiTestIdentifier === "string" && (test.sortOrder === null || Number.isInteger(test.sortOrder)) && typeof test.updatedAt === "string" && typeof test.live === "boolean" && isRecord(test.assessment) && typeof test.assessment.identifier === "string" && typeof test.assessment.
|
|
6061
|
+
return catalog.tests.every((test) => isRecord(test) && typeof test.id === "string" && typeof test.qtiTestIdentifier === "string" && (test.sortOrder === null || Number.isInteger(test.sortOrder)) && typeof test.updatedAt === "string" && typeof test.live === "boolean" && isRecord(test.assessment) && typeof test.assessment.identifier === "string" && Number.isInteger(test.assessment.contractVersion) && typeof test.assessment.contentRevision === "string" && Array.isArray(test.assessment.items) && isRecord(test.correctResponses));
|
|
5694
6062
|
});
|
|
5695
6063
|
}
|
|
5696
|
-
var ASSESSMENT_ATTEMPT_OPEN, ASSESSMENT_ATTEMPT_COMPLETED, ASSESSMENT_RUNTIME_ERROR_STATUS, GRADE_VALUES, RuntimeSubjectSchema, RuntimeGradeSchema, OptionalQueryGradeSchema, AssessmentResponseValueSchema, AssessmentRuntimeIdentitySchema, LatestAssessmentFiltersSchema, LatestRuntimeAssessmentQuerySchema, ResponseKeySchema, StartAssessmentBodySchema, SaveAssessmentBodySchema, SubmitAssessmentBodySchema, StartRuntimeAssessmentRequestSchema, SaveRuntimeAssessmentRequestSchema, SubmitRuntimeAssessmentRequestSchema;
|
|
6064
|
+
var ASSESSMENT_ATTEMPT_OPEN, ASSESSMENT_ATTEMPT_COMPLETED, ASSESSMENT_RUNTIME_ERROR_STATUS, GRADE_VALUES, POINT_RESPONSE_PATTERN, RuntimeSubjectSchema, RuntimeGradeSchema, OptionalQueryGradeSchema, AssessmentResponseValueSchema, AssessmentRuntimeIdentitySchema, LatestAssessmentFiltersSchema, LatestRuntimeAssessmentQuerySchema, ResponseKeySchema, StartAssessmentBodySchema, SaveAssessmentBodySchema, SubmitAssessmentBodySchema, StartRuntimeAssessmentRequestSchema, SaveRuntimeAssessmentRequestSchema, SubmitRuntimeAssessmentRequestSchema;
|
|
5697
6065
|
var init_assessment_runtime = __esm({
|
|
5698
6066
|
"../timeback/dist/engines/assessment-runtime/index.js"() {
|
|
5699
6067
|
"use strict";
|
|
5700
6068
|
init_src();
|
|
6069
|
+
init_timeback3();
|
|
5701
6070
|
init_src();
|
|
5702
6071
|
init_fns();
|
|
5703
6072
|
init_src();
|
|
@@ -5722,6 +6091,7 @@ var init_assessment_runtime = __esm({
|
|
|
5722
6091
|
ATTEMPT_ALREADY_SUBMITTED: 409
|
|
5723
6092
|
};
|
|
5724
6093
|
GRADE_VALUES = TIMEBACK_GRADES;
|
|
6094
|
+
POINT_RESPONSE_PATTERN = /^-?\d+(?:\.\d+)? -?\d+(?:\.\d+)?$/;
|
|
5725
6095
|
RuntimeSubjectSchema = external_exports.enum(TIMEBACK_SUBJECTS);
|
|
5726
6096
|
RuntimeGradeSchema = external_exports.number().refine(isTimebackGrade, {
|
|
5727
6097
|
message: `Grade must be one of: ${TIMEBACK_GRADES.join(", ")}`
|
|
@@ -5832,7 +6202,7 @@ var init_local_assessment_runtime = __esm({
|
|
|
5832
6202
|
activityId: input.activityId,
|
|
5833
6203
|
selectedTest: {
|
|
5834
6204
|
identifier: selection.test.qtiTestIdentifier,
|
|
5835
|
-
contentRevision: this.fixtureTest(catalog, selection.test.qtiTestIdentifier).assessment.
|
|
6205
|
+
contentRevision: this.fixtureTest(catalog, selection.test.qtiTestIdentifier).assessment.contentRevision
|
|
5836
6206
|
},
|
|
5837
6207
|
responseVersion: 0,
|
|
5838
6208
|
responses: {},
|
|
@@ -5880,6 +6250,13 @@ var init_local_assessment_runtime = __esm({
|
|
|
5880
6250
|
this.assertInProgress(attempt);
|
|
5881
6251
|
this.assertResponseVersion(attempt, input.expectedResponseVersion);
|
|
5882
6252
|
const test = this.testForAttempt(attempt);
|
|
6253
|
+
const updateMessage = assessmentResponseUpdateValidationMessage(
|
|
6254
|
+
test.assessment,
|
|
6255
|
+
input.responses
|
|
6256
|
+
);
|
|
6257
|
+
if (updateMessage) {
|
|
6258
|
+
throw runtimeError("INVALID_RESPONSE", updateMessage);
|
|
6259
|
+
}
|
|
5883
6260
|
const responses = applyAssessmentResponseUpdate(attempt.responses, input.responses);
|
|
5884
6261
|
const validationMessage = assessmentResponseValidationMessage(test.assessment, responses);
|
|
5885
6262
|
if (validationMessage) {
|
|
@@ -5984,7 +6361,7 @@ var init_local_assessment_runtime = __esm({
|
|
|
5984
6361
|
}
|
|
5985
6362
|
fixtureTest(catalog, identifier, revision) {
|
|
5986
6363
|
const test = catalog.tests.find(
|
|
5987
|
-
(candidate) => candidate.qtiTestIdentifier === identifier && (revision === void 0 || candidate.assessment.
|
|
6364
|
+
(candidate) => candidate.qtiTestIdentifier === identifier && (revision === void 0 || candidate.assessment.contentRevision === revision)
|
|
5988
6365
|
);
|
|
5989
6366
|
if (!test) {
|
|
5990
6367
|
throw runtimeError(
|
|
@@ -6114,54 +6491,6 @@ var init_errors3 = __esm({
|
|
|
6114
6491
|
}
|
|
6115
6492
|
});
|
|
6116
6493
|
|
|
6117
|
-
// ../utils/src/timeback.ts
|
|
6118
|
-
function formatGradeLabel(grade) {
|
|
6119
|
-
if (grade === null || grade === void 0) {
|
|
6120
|
-
return "N/A";
|
|
6121
|
-
}
|
|
6122
|
-
switch (grade) {
|
|
6123
|
-
case -1: {
|
|
6124
|
-
return "Pre-K";
|
|
6125
|
-
}
|
|
6126
|
-
case 0: {
|
|
6127
|
-
return "Kindergarten";
|
|
6128
|
-
}
|
|
6129
|
-
case 13: {
|
|
6130
|
-
return "AP";
|
|
6131
|
-
}
|
|
6132
|
-
default: {
|
|
6133
|
-
return `Grade ${grade}`;
|
|
6134
|
-
}
|
|
6135
|
-
}
|
|
6136
|
-
}
|
|
6137
|
-
var TIMEBACK_DISCREPANCY_QUEUE_WINDOWS, TIMEBACK_DISCREPANCY_QUEUE_METRICS, PLAYCADEMY_SUPPORTED_QTI_INTERACTION_TYPES, PLAYCADEMY_SUPPORTED_QTI_INTERACTION_TYPE_SET, TIMEBACK_DISCREPANCY_QUEUE_WINDOW_VALUES, TIMEBACK_DISCREPANCY_QUEUE_METRIC_VALUES;
|
|
6138
|
-
var init_timeback3 = __esm({
|
|
6139
|
-
"../utils/src/timeback.ts"() {
|
|
6140
|
-
TIMEBACK_DISCREPANCY_QUEUE_WINDOWS = [
|
|
6141
|
-
"today",
|
|
6142
|
-
"yesterday",
|
|
6143
|
-
"this-week",
|
|
6144
|
-
"last-week",
|
|
6145
|
-
"all",
|
|
6146
|
-
"custom"
|
|
6147
|
-
];
|
|
6148
|
-
TIMEBACK_DISCREPANCY_QUEUE_METRICS = ["xp", "mastery", "time", "score"];
|
|
6149
|
-
PLAYCADEMY_SUPPORTED_QTI_INTERACTION_TYPES = [
|
|
6150
|
-
"choice",
|
|
6151
|
-
"inline-choice",
|
|
6152
|
-
"text-entry",
|
|
6153
|
-
"order",
|
|
6154
|
-
"match",
|
|
6155
|
-
"hottext"
|
|
6156
|
-
];
|
|
6157
|
-
PLAYCADEMY_SUPPORTED_QTI_INTERACTION_TYPE_SET = new Set(
|
|
6158
|
-
PLAYCADEMY_SUPPORTED_QTI_INTERACTION_TYPES
|
|
6159
|
-
);
|
|
6160
|
-
TIMEBACK_DISCREPANCY_QUEUE_WINDOW_VALUES = new Set(TIMEBACK_DISCREPANCY_QUEUE_WINDOWS);
|
|
6161
|
-
TIMEBACK_DISCREPANCY_QUEUE_METRIC_VALUES = new Set(TIMEBACK_DISCREPANCY_QUEUE_METRICS);
|
|
6162
|
-
}
|
|
6163
|
-
});
|
|
6164
|
-
|
|
6165
6494
|
// ../edge-play/src/game/lib/validation.ts
|
|
6166
6495
|
function isNonNegativeNumber(value) {
|
|
6167
6496
|
return typeof value === "number" && Number.isFinite(value) && value >= 0;
|
|
@@ -6510,9 +6839,9 @@ var init_list = __esm({
|
|
|
6510
6839
|
// ../edge-play/src/game/lib/metadata.ts
|
|
6511
6840
|
function getRuntimeMetadata() {
|
|
6512
6841
|
return {
|
|
6513
|
-
cliVersion: true ? "0.28.1-beta.
|
|
6514
|
-
sdkVersion: true ? "0.16.1-beta.
|
|
6515
|
-
buildId: true ? "
|
|
6842
|
+
cliVersion: true ? "0.28.1-beta.6" : "0.0.0-dev",
|
|
6843
|
+
sdkVersion: true ? "0.16.1-beta.6" : "0.0.0-dev",
|
|
6844
|
+
buildId: true ? "0a295619c459" : "dev-source"
|
|
6516
6845
|
};
|
|
6517
6846
|
}
|
|
6518
6847
|
var init_metadata = __esm({
|
|
@@ -9107,28 +9436,28 @@ async function verifyGameToken(gameToken, options) {
|
|
|
9107
9436
|
body: JSON.stringify({ token: gameToken })
|
|
9108
9437
|
});
|
|
9109
9438
|
if (!response.ok) {
|
|
9110
|
-
let
|
|
9439
|
+
let errorMessage2 = "Unknown error";
|
|
9111
9440
|
try {
|
|
9112
9441
|
const data = await response.json();
|
|
9113
9442
|
const errorField = data.error || data.message;
|
|
9114
9443
|
if (typeof errorField === "string") {
|
|
9115
|
-
|
|
9444
|
+
errorMessage2 = errorField;
|
|
9116
9445
|
} else if (errorField && typeof errorField === "object") {
|
|
9117
9446
|
const errorObj = errorField;
|
|
9118
9447
|
if ("message" in errorObj && typeof errorObj.message === "string") {
|
|
9119
|
-
|
|
9448
|
+
errorMessage2 = errorObj.message;
|
|
9120
9449
|
if ("code" in errorObj && typeof errorObj.code === "string") {
|
|
9121
|
-
|
|
9450
|
+
errorMessage2 = `[${errorObj.code}] ${errorMessage2}`;
|
|
9122
9451
|
}
|
|
9123
9452
|
} else {
|
|
9124
|
-
|
|
9453
|
+
errorMessage2 = JSON.stringify(errorField);
|
|
9125
9454
|
}
|
|
9126
9455
|
}
|
|
9127
9456
|
} catch {
|
|
9128
|
-
|
|
9457
|
+
errorMessage2 = response.statusText || "Unknown error";
|
|
9129
9458
|
}
|
|
9130
9459
|
throw new Error(
|
|
9131
|
-
`[Playcademy SDK] Token verification failed: ${response.status} ${
|
|
9460
|
+
`[Playcademy SDK] Token verification failed: ${response.status} ${errorMessage2}`
|
|
9132
9461
|
);
|
|
9133
9462
|
}
|
|
9134
9463
|
const result = await response.json();
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
|
-
"cliVersion": "0.28.1-beta.
|
|
3
|
-
"sdkVersion": "0.16.1-beta.
|
|
4
|
-
"runtimeBuildId": "
|
|
5
|
-
"inputFingerprint": "
|
|
2
|
+
"cliVersion": "0.28.1-beta.6",
|
|
3
|
+
"sdkVersion": "0.16.1-beta.6",
|
|
4
|
+
"runtimeBuildId": "0a295619c459",
|
|
5
|
+
"inputFingerprint": "0a295619c459fabba64e443c7824867a149bce88a5cfee63d7a97852609a617e",
|
|
6
6
|
"entry": "index.js"
|
|
7
7
|
}
|
package/dist/utils.js
CHANGED
|
@@ -383,7 +383,7 @@ var DASHBOARD_API_ROUTES_DIRECTORY = "api";
|
|
|
383
383
|
// ../better-auth/package.json
|
|
384
384
|
var package_default = {
|
|
385
385
|
name: "@playcademy/better-auth",
|
|
386
|
-
version: "0.0.21-beta.
|
|
386
|
+
version: "0.0.21-beta.6",
|
|
387
387
|
type: "module",
|
|
388
388
|
exports: {
|
|
389
389
|
"./server": {
|
|
@@ -1508,11 +1508,44 @@ var PLAYCADEMY_SUPPORTED_QTI_INTERACTION_TYPES = [
|
|
|
1508
1508
|
"text-entry",
|
|
1509
1509
|
"order",
|
|
1510
1510
|
"match",
|
|
1511
|
-
"hottext"
|
|
1511
|
+
"hottext",
|
|
1512
|
+
"hotspot",
|
|
1513
|
+
"gap-match",
|
|
1514
|
+
"graphic-gap-match",
|
|
1515
|
+
"select-point",
|
|
1516
|
+
"graphic-associate",
|
|
1517
|
+
"position-object"
|
|
1512
1518
|
];
|
|
1513
1519
|
var PLAYCADEMY_SUPPORTED_QTI_INTERACTION_TYPE_SET = new Set(
|
|
1514
1520
|
PLAYCADEMY_SUPPORTED_QTI_INTERACTION_TYPES
|
|
1515
1521
|
);
|
|
1522
|
+
var PLAYCADEMY_AUTHORABLE_QTI_INTERACTION_TYPES = [
|
|
1523
|
+
"choice",
|
|
1524
|
+
"inline-choice",
|
|
1525
|
+
"text-entry",
|
|
1526
|
+
"order",
|
|
1527
|
+
"match",
|
|
1528
|
+
"hottext",
|
|
1529
|
+
"gap-match",
|
|
1530
|
+
"hotspot",
|
|
1531
|
+
"graphic-associate",
|
|
1532
|
+
"graphic-gap-match"
|
|
1533
|
+
];
|
|
1534
|
+
var PLAYCADEMY_AUTHORABLE_QTI_INTERACTION_TYPE_SET = new Set(
|
|
1535
|
+
PLAYCADEMY_AUTHORABLE_QTI_INTERACTION_TYPES
|
|
1536
|
+
);
|
|
1537
|
+
var QTI_RASTER_IMAGE_MIME_TYPES = [
|
|
1538
|
+
"image/png",
|
|
1539
|
+
"image/jpeg",
|
|
1540
|
+
// Some browsers and operating systems still report the legacy jpg spelling.
|
|
1541
|
+
"image/jpg",
|
|
1542
|
+
"image/gif",
|
|
1543
|
+
"image/webp",
|
|
1544
|
+
"image/bmp"
|
|
1545
|
+
];
|
|
1546
|
+
var QTI_RASTER_IMAGE_SUBTYPE_PATTERN = QTI_RASTER_IMAGE_MIME_TYPES.map(
|
|
1547
|
+
(type) => type.slice("image/".length)
|
|
1548
|
+
).join("|");
|
|
1516
1549
|
var TIMEBACK_DISCREPANCY_QUEUE_WINDOW_VALUES = new Set(TIMEBACK_DISCREPANCY_QUEUE_WINDOWS);
|
|
1517
1550
|
var TIMEBACK_DISCREPANCY_QUEUE_METRIC_VALUES = new Set(TIMEBACK_DISCREPANCY_QUEUE_METRICS);
|
|
1518
1551
|
|
|
@@ -2794,7 +2827,7 @@ import { existsSync as existsSync9, mkdirSync as mkdirSync2, writeFileSync as wr
|
|
|
2794
2827
|
import { dirname as dirname4, join as join14 } from "node:path";
|
|
2795
2828
|
|
|
2796
2829
|
// src/version.ts
|
|
2797
|
-
var cliVersion = false ? "0.0.0-dev" : "0.28.1-beta.
|
|
2830
|
+
var cliVersion = false ? "0.0.0-dev" : "0.28.1-beta.6";
|
|
2798
2831
|
|
|
2799
2832
|
// src/lib/build/binary-resource.ts
|
|
2800
2833
|
function writeFileTree(baseDir, files) {
|
|
@@ -10268,14 +10301,14 @@ function isAssessmentResponseValue(value) {
|
|
|
10268
10301
|
return entries.length > 0 && entries.every((entry) => typeof entry === "string" && entry.length > 0 && entry.length <= TIMEBACK_ASSESSMENT_RESPONSE_VALUE_MAX_LENGTH);
|
|
10269
10302
|
}
|
|
10270
10303
|
function isAssessmentRuntimeFixtureBundle(value) {
|
|
10271
|
-
if (!isRecord(value) || value.version !==
|
|
10304
|
+
if (!isRecord(value) || value.version !== 3 || typeof value.gameId !== "string" || typeof value.exportedAt !== "string" || !Array.isArray(value.catalogs)) {
|
|
10272
10305
|
return false;
|
|
10273
10306
|
}
|
|
10274
10307
|
return value.catalogs.every((catalog) => {
|
|
10275
10308
|
if (!isRecord(catalog) || typeof catalog.id !== "string" || typeof catalog.integrationId !== "string" || !isAssessmentPurpose(catalog.purpose) || typeof catalog.subject !== "string" || !Number.isInteger(catalog.grade) || !Array.isArray(catalog.tests)) {
|
|
10276
10309
|
return false;
|
|
10277
10310
|
}
|
|
10278
|
-
return catalog.tests.every((test) => isRecord(test) && typeof test.id === "string" && typeof test.qtiTestIdentifier === "string" && (test.sortOrder === null || Number.isInteger(test.sortOrder)) && typeof test.updatedAt === "string" && typeof test.live === "boolean" && isRecord(test.assessment) && typeof test.assessment.identifier === "string" && typeof test.assessment.
|
|
10311
|
+
return catalog.tests.every((test) => isRecord(test) && typeof test.id === "string" && typeof test.qtiTestIdentifier === "string" && (test.sortOrder === null || Number.isInteger(test.sortOrder)) && typeof test.updatedAt === "string" && typeof test.live === "boolean" && isRecord(test.assessment) && typeof test.assessment.identifier === "string" && Number.isInteger(test.assessment.contractVersion) && typeof test.assessment.contentRevision === "string" && Array.isArray(test.assessment.items) && isRecord(test.correctResponses));
|
|
10279
10312
|
});
|
|
10280
10313
|
}
|
|
10281
10314
|
var RuntimeSubjectSchema = external_exports.enum(TIMEBACK_SUBJECTS);
|
package/dist/version.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "playcademy",
|
|
3
|
-
"version": "0.28.1-beta.
|
|
3
|
+
"version": "0.28.1-beta.6",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": {
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
},
|
|
56
56
|
"dependencies": {
|
|
57
57
|
"@inquirer/prompts": "^7.8.6",
|
|
58
|
-
"@playcademy/sdk": "0.16.1-beta.
|
|
58
|
+
"@playcademy/sdk": "0.16.1-beta.6",
|
|
59
59
|
"chokidar": "^4.0.3",
|
|
60
60
|
"colorette": "^2.0.20",
|
|
61
61
|
"commander": "^14.0.1",
|