@thanh01.pmt/interactive-quiz-kit 1.0.24 → 1.0.25

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -5,26 +5,6 @@ import JSZip from 'jszip';
5
5
  import { clsx } from 'clsx';
6
6
  import { twMerge } from 'tailwind-merge';
7
7
 
8
- var __defProp = Object.defineProperty;
9
- var __defProps = Object.defineProperties;
10
- var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
11
- var __getOwnPropSymbols = Object.getOwnPropertySymbols;
12
- var __hasOwnProp = Object.prototype.hasOwnProperty;
13
- var __propIsEnum = Object.prototype.propertyIsEnumerable;
14
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
15
- var __spreadValues = (a, b) => {
16
- for (var prop in b || (b = {}))
17
- if (__hasOwnProp.call(b, prop))
18
- __defNormalProp(a, prop, b[prop]);
19
- if (__getOwnPropSymbols)
20
- for (var prop of __getOwnPropSymbols(b)) {
21
- if (__propIsEnum.call(b, prop))
22
- __defNormalProp(a, prop, b[prop]);
23
- }
24
- return a;
25
- };
26
- var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
27
-
28
8
  // src/services/SCORMService.ts
29
9
  var SCORM_TRUE = "true";
30
10
  var SCORM_NO_ERROR = "0";
@@ -44,11 +24,12 @@ var SCORMService = class {
44
24
  this.isInitialized = false;
45
25
  this.isTerminated = false;
46
26
  this.studentName = null;
47
- this.settings = __spreadValues({
27
+ this.settings = {
48
28
  setCompletionOnFinish: true,
49
29
  setSuccessOnPass: true,
50
- autoCommit: true
51
- }, settings);
30
+ autoCommit: true,
31
+ ...settings
32
+ };
52
33
  if (typeof window !== "undefined") {
53
34
  this._findAPI();
54
35
  }
@@ -154,14 +135,13 @@ var SCORMService = class {
154
135
  }
155
136
  }
156
137
  getValue(element) {
157
- var _a;
158
138
  if (!this.hasAPI() || !this.isInitialized) return null;
159
139
  const value = this.scormVersionFound === "2004" ? this.scormAPI.GetValue(element) : this.scormAPI.LMSGetValue(element);
160
140
  const error = this.getLastError();
161
141
  if (error.code !== SCORM_NO_ERROR && error.code !== "403" && error.code !== "0") {
162
142
  console.warn(`SCORMService: GetValue for ${element} produced an error ${error.code}: ${error.message}. Returning raw value:`, value);
163
143
  }
164
- return (_a = value == null ? void 0 : value.toString()) != null ? _a : null;
144
+ return value?.toString() ?? null;
165
145
  }
166
146
  commit() {
167
147
  if (!this.hasAPI() || !this.isInitialized) {
@@ -233,7 +213,6 @@ var SCORMService = class {
233
213
  }
234
214
  }
235
215
  getLastError() {
236
- var _a, _b;
237
216
  if (!this.hasAPI()) return { code: "-1", message: "SCORM API not found." };
238
217
  const errorCode = this.scormVersionFound === "2004" ? this.scormAPI.GetLastError() : this.scormAPI.LMSGetLastError();
239
218
  if (errorCode === SCORM_NO_ERROR || errorCode === 0 || errorCode === "0") {
@@ -243,8 +222,8 @@ var SCORMService = class {
243
222
  const diagnostic = this.scormVersionFound === "2004" ? this.scormAPI.GetDiagnostic(errorCode.toString()) : this.scormAPI.LMSGetDiagnostic(errorCode.toString());
244
223
  return {
245
224
  code: errorCode.toString(),
246
- message: (_a = errorMessage == null ? void 0 : errorMessage.toString()) != null ? _a : "Unknown error.",
247
- diagnostic: (_b = diagnostic == null ? void 0 : diagnostic.toString()) != null ? _b : void 0
225
+ message: errorMessage?.toString() ?? "Unknown error.",
226
+ diagnostic: diagnostic?.toString() ?? void 0
248
227
  };
249
228
  }
250
229
  formatCMITime(totalSeconds) {
@@ -275,14 +254,13 @@ var SCORMService = class {
275
254
  // src/services/evaluators/multiple-choice-evaluator.ts
276
255
  var MultipleChoiceEvaluator = class {
277
256
  async evaluate(question, answer) {
278
- var _a;
279
- const points = (_a = question.points) != null ? _a : 0;
257
+ const points = question.points ?? 0;
280
258
  const correctAnswerId = question.correctAnswerId;
281
259
  const isCorrect = answer === correctAnswerId;
282
260
  const correctOption = question.options.find((opt) => opt.id === correctAnswerId);
283
261
  const correctAnswerDetail = {
284
262
  id: correctAnswerId,
285
- value: (correctOption == null ? void 0 : correctOption.text) || ""
263
+ value: correctOption?.text || ""
286
264
  };
287
265
  return Promise.resolve({
288
266
  isCorrect,
@@ -295,8 +273,7 @@ var MultipleChoiceEvaluator = class {
295
273
  // src/services/evaluators/multiple-response-evaluator.ts
296
274
  var MultipleResponseEvaluator = class {
297
275
  async evaluate(question, answer) {
298
- var _a;
299
- const points = (_a = question.points) != null ? _a : 0;
276
+ const points = question.points ?? 0;
300
277
  const correctAnswerIds = question.correctAnswerIds;
301
278
  let isCorrect = false;
302
279
  if (Array.isArray(answer)) {
@@ -305,10 +282,7 @@ var MultipleResponseEvaluator = class {
305
282
  isCorrect = userAnswerSet.size === correctAnswerSet.size && [...userAnswerSet].every((id) => correctAnswerSet.has(id));
306
283
  }
307
284
  const correctValues = correctAnswerIds.map(
308
- (id) => {
309
- var _a2;
310
- return ((_a2 = question.options.find((opt) => opt.id === id)) == null ? void 0 : _a2.text) || "";
311
- }
285
+ (id) => question.options.find((opt) => opt.id === id)?.text || ""
312
286
  );
313
287
  const correctAnswerDetail = {
314
288
  id: correctAnswerIds,
@@ -325,8 +299,7 @@ var MultipleResponseEvaluator = class {
325
299
  // src/services/evaluators/true-false-evaluator.ts
326
300
  var TrueFalseEvaluator = class {
327
301
  async evaluate(question, answer) {
328
- var _a;
329
- const points = (_a = question.points) != null ? _a : 0;
302
+ const points = question.points ?? 0;
330
303
  const correctAnswer = question.correctAnswer;
331
304
  let userAnswer = answer;
332
305
  if (typeof answer === "string") {
@@ -348,12 +321,11 @@ var TrueFalseEvaluator = class {
348
321
  // src/services/evaluators/short-answer-evaluator.ts
349
322
  var ShortAnswerEvaluator = class {
350
323
  async evaluate(question, answer) {
351
- var _a, _b;
352
- const points = (_a = question.points) != null ? _a : 0;
324
+ const points = question.points ?? 0;
353
325
  let isCorrect = false;
354
326
  if (typeof answer === "string") {
355
327
  const userAnswerTrimmed = answer.trim();
356
- const caseSensitive = (_b = question.isCaseSensitive) != null ? _b : false;
328
+ const caseSensitive = question.isCaseSensitive ?? false;
357
329
  isCorrect = question.acceptedAnswers.some(
358
330
  (accAns) => caseSensitive ? accAns.trim() === userAnswerTrimmed : accAns.trim().toLowerCase() === userAnswerTrimmed.toLowerCase()
359
331
  );
@@ -373,8 +345,7 @@ var ShortAnswerEvaluator = class {
373
345
  // src/services/evaluators/numeric-evaluator.ts
374
346
  var NumericEvaluator = class {
375
347
  async evaluate(question, answer) {
376
- var _a;
377
- const points = (_a = question.points) != null ? _a : 0;
348
+ const points = question.points ?? 0;
378
349
  let isCorrect = false;
379
350
  if (typeof answer === "string" || typeof answer === "number") {
380
351
  const userAnswerNum = parseFloat(String(answer));
@@ -397,17 +368,13 @@ var NumericEvaluator = class {
397
368
  // src/services/evaluators/sequence-evaluator.ts
398
369
  var SequenceEvaluator = class {
399
370
  async evaluate(question, answer) {
400
- var _a;
401
- const points = (_a = question.points) != null ? _a : 0;
371
+ const points = question.points ?? 0;
402
372
  let isCorrect = false;
403
373
  if (Array.isArray(answer) && answer.length === question.correctOrder.length) {
404
374
  isCorrect = answer.every((itemId, index) => itemId === question.correctOrder[index]);
405
375
  }
406
376
  const correctValues = question.correctOrder.map(
407
- (id) => {
408
- var _a2;
409
- return ((_a2 = question.items.find((item) => item.id === id)) == null ? void 0 : _a2.content) || "";
410
- }
377
+ (id) => question.items.find((item) => item.id === id)?.content || ""
411
378
  );
412
379
  const correctAnswerDetail = {
413
380
  id: question.correctOrder,
@@ -424,17 +391,15 @@ var SequenceEvaluator = class {
424
391
  // src/services/evaluators/matching-evaluator.ts
425
392
  var MatchingEvaluator = class {
426
393
  async evaluate(question, answer) {
427
- var _a;
428
- const points = (_a = question.points) != null ? _a : 0;
394
+ const points = question.points ?? 0;
429
395
  let isCorrect = false;
430
396
  if (typeof answer === "object" && answer !== null && !Array.isArray(answer)) {
431
397
  const userAnswerMap = answer;
432
398
  isCorrect = question.correctAnswerMap.length === Object.keys(userAnswerMap).length && question.correctAnswerMap.every((map) => userAnswerMap[map.promptId] === map.optionId);
433
399
  }
434
400
  const correctMap = question.correctAnswerMap.reduce((acc, curr) => {
435
- var _a2, _b;
436
- const promptText = ((_a2 = question.prompts.find((p) => p.id === curr.promptId)) == null ? void 0 : _a2.content) || "";
437
- const optionText = ((_b = question.options.find((o) => o.id === curr.optionId)) == null ? void 0 : _b.content) || "";
401
+ const promptText = question.prompts.find((p) => p.id === curr.promptId)?.content || "";
402
+ const optionText = question.options.find((o) => o.id === curr.optionId)?.content || "";
438
403
  acc[promptText] = optionText;
439
404
  return acc;
440
405
  }, {});
@@ -453,16 +418,14 @@ var MatchingEvaluator = class {
453
418
  // src/services/evaluators/fill-in-the-blanks-evaluator.ts
454
419
  var FillInTheBlanksEvaluator = class {
455
420
  async evaluate(question, answer) {
456
- var _a;
457
- const points = (_a = question.points) != null ? _a : 0;
421
+ const points = question.points ?? 0;
458
422
  let isCorrect = false;
459
423
  if (typeof answer === "object" && answer !== null && !Array.isArray(answer)) {
460
424
  const userAnswerMap = answer;
461
425
  isCorrect = question.answers.length > 0 && question.answers.every((correctAnsDef) => {
462
- var _a2, _b;
463
- const userValForBlank = (_a2 = userAnswerMap[correctAnsDef.blankId]) == null ? void 0 : _a2.trim();
426
+ const userValForBlank = userAnswerMap[correctAnsDef.blankId]?.trim();
464
427
  if (userValForBlank === void 0) return false;
465
- const caseSensitive = (_b = question.isCaseSensitive) != null ? _b : false;
428
+ const caseSensitive = question.isCaseSensitive ?? false;
466
429
  return correctAnsDef.acceptedValues.some(
467
430
  (accVal) => caseSensitive ? accVal.trim() === userValForBlank : accVal.trim().toLowerCase() === userValForBlank.toLowerCase()
468
431
  );
@@ -487,17 +450,15 @@ var FillInTheBlanksEvaluator = class {
487
450
  // src/services/evaluators/drag-and-drop-evaluator.ts
488
451
  var DragAndDropEvaluator = class {
489
452
  async evaluate(question, answer) {
490
- var _a;
491
- const points = (_a = question.points) != null ? _a : 0;
453
+ const points = question.points ?? 0;
492
454
  let isCorrect = false;
493
455
  if (typeof answer === "object" && answer !== null && !Array.isArray(answer)) {
494
456
  const userAnswerMap = answer;
495
457
  isCorrect = question.answerMap.length === Object.keys(userAnswerMap).length && question.answerMap.every((map) => userAnswerMap[map.draggableId] === map.dropZoneId);
496
458
  }
497
459
  const correctMap = question.answerMap.reduce((acc, curr) => {
498
- var _a2, _b;
499
- const draggableText = ((_a2 = question.draggableItems.find((d) => d.id === curr.draggableId)) == null ? void 0 : _a2.content) || "";
500
- const dropZoneText = ((_b = question.dropZones.find((z4) => z4.id === curr.dropZoneId)) == null ? void 0 : _b.label) || "";
460
+ const draggableText = question.draggableItems.find((d) => d.id === curr.draggableId)?.content || "";
461
+ const dropZoneText = question.dropZones.find((z4) => z4.id === curr.dropZoneId)?.label || "";
501
462
  acc[draggableText] = dropZoneText;
502
463
  return acc;
503
464
  }, {});
@@ -516,8 +477,7 @@ var DragAndDropEvaluator = class {
516
477
  // src/services/evaluators/hotspot-evaluator.ts
517
478
  var HotspotEvaluator = class {
518
479
  async evaluate(question, answer) {
519
- var _a;
520
- const points = (_a = question.points) != null ? _a : 0;
480
+ const points = question.points ?? 0;
521
481
  let isCorrect = false;
522
482
  if (Array.isArray(answer)) {
523
483
  const userAnswerSet = new Set(answer);
@@ -525,10 +485,7 @@ var HotspotEvaluator = class {
525
485
  isCorrect = userAnswerSet.size === correctAnswerSet.size && [...userAnswerSet].every((id) => correctAnswerSet.has(id));
526
486
  }
527
487
  const correctValues = question.correctHotspotIds.map(
528
- (id) => {
529
- var _a2;
530
- return ((_a2 = question.hotspots.find((h) => h.id === id)) == null ? void 0 : _a2.description) || id;
531
- }
488
+ (id) => question.hotspots.find((h) => h.id === id)?.description || id
532
489
  );
533
490
  const correctAnswerDetail = {
534
491
  id: question.correctHotspotIds,
@@ -545,11 +502,10 @@ var HotspotEvaluator = class {
545
502
  // src/services/evaluators/programming-evaluator.ts
546
503
  var ProgrammingEvaluator = class {
547
504
  async evaluate(question, answer) {
548
- var _a, _b;
549
- const points = (_a = question.points) != null ? _a : 0;
505
+ const points = question.points ?? 0;
550
506
  let isCorrect = false;
551
507
  if (typeof answer === "string" && typeof question.solutionGeneratedCode === "string") {
552
- if (typeof window !== "undefined" && ((_b = window.Blockly) == null ? void 0 : _b.JavaScript)) {
508
+ if (typeof window !== "undefined" && window.Blockly?.JavaScript) {
553
509
  const LocalBlockly = window.Blockly;
554
510
  let generatedUserCode = "";
555
511
  try {
@@ -623,10 +579,10 @@ var JsonRepairEngine = class {
623
579
  if (breakIndex !== -1) {
624
580
  const stringContent = afterUnterminated.substring(0, breakIndex);
625
581
  const remainder = afterUnterminated.substring(breakIndex);
626
- const escapedContent = stringContent.replace(new RegExp('(?<!\\\\)"', "g"), '\\"');
582
+ const escapedContent = stringContent.replace(/(?<!\\)"/g, '\\"');
627
583
  repaired = beforeUnterminated + escapedContent + '"' + remainder;
628
584
  } else {
629
- const escapedContent = afterUnterminated.replace(new RegExp('(?<!\\\\)"', "g"), '\\"');
585
+ const escapedContent = afterUnterminated.replace(/(?<!\\)"/g, '\\"');
630
586
  repaired = beforeUnterminated + escapedContent + '"';
631
587
  }
632
588
  }
@@ -702,7 +658,6 @@ var JsonRepairEngine = class {
702
658
  * Main repair function that attempts multiple strategies.
703
659
  */
704
660
  static repairJson(jsonStr) {
705
- var _a;
706
661
  let current = jsonStr.trim();
707
662
  const maxAttempts = 5;
708
663
  let lastError = "";
@@ -732,7 +687,7 @@ var JsonRepairEngine = class {
732
687
  }
733
688
  lastError = validation.error || "";
734
689
  lastPosition = validation.position;
735
- if ((_a = validation.error) == null ? void 0 : _a.includes("Unterminated string")) {
690
+ if (validation.error?.includes("Unterminated string")) {
736
691
  current = this.repairUnterminatedStrings(current);
737
692
  } else {
738
693
  current = this.applyCommonFixes(current);
@@ -1027,9 +982,10 @@ var CodeEvaluationService = class {
1027
982
  userCode,
1028
983
  testCase
1029
984
  }, this.apiKey);
1030
- return __spreadValues({
1031
- testCaseId: testCase.id
1032
- }, aiResult);
985
+ return {
986
+ testCaseId: testCase.id,
987
+ ...aiResult
988
+ };
1033
989
  }
1034
990
  /**
1035
991
  * Evaluates user's code against all test cases for a given question.
@@ -1066,8 +1022,7 @@ var CodeEvaluationService = class {
1066
1022
  // src/services/evaluators/coding-evaluator.ts
1067
1023
  var CodingEvaluator = class {
1068
1024
  async evaluate(question, answer) {
1069
- var _a;
1070
- const points = (_a = question.points) != null ? _a : 0;
1025
+ const points = question.points ?? 0;
1071
1026
  if (typeof answer !== "string" || !answer.trim()) {
1072
1027
  return {
1073
1028
  isCorrect: false,
@@ -1124,17 +1079,16 @@ var QuizEngine = class {
1124
1079
  this.quizResultState = { scormStatus: "idle" };
1125
1080
  this.questionStartTime = null;
1126
1081
  this.questionTimings = /* @__PURE__ */ new Map();
1127
- var _a, _b, _c, _d, _e;
1128
1082
  this.config = options.config;
1129
1083
  this.callbacks = options.callbacks || {};
1130
- this.questions = ((_a = this.config.settings) == null ? void 0 : _a.shuffleQuestions) ? [...this.config.questions].sort(() => Math.random() - 0.5) : this.config.questions;
1084
+ this.questions = this.config.settings?.shuffleQuestions ? [...this.config.questions].sort(() => Math.random() - 0.5) : this.config.questions;
1131
1085
  this.overallStartTime = Date.now();
1132
1086
  this.evaluators = /* @__PURE__ */ new Map();
1133
1087
  this.registerEvaluators();
1134
- if (((_b = this.config.settings) == null ? void 0 : _b.timeLimitMinutes) && this.config.settings.timeLimitMinutes > 0) {
1088
+ if (this.config.settings?.timeLimitMinutes && this.config.settings.timeLimitMinutes > 0) {
1135
1089
  this.timeLeftInSeconds = this.config.settings.timeLimitMinutes * 60;
1136
1090
  }
1137
- if ((_c = this.config.settings) == null ? void 0 : _c.scorm) {
1091
+ if (this.config.settings?.scorm) {
1138
1092
  this.quizResultState.scormStatus = "initializing";
1139
1093
  this.scormService = new SCORMService(this.config.settings.scorm);
1140
1094
  if (this.scormService.hasAPI()) {
@@ -1167,7 +1121,7 @@ var QuizEngine = class {
1167
1121
  if (this.timeLeftInSeconds !== null) {
1168
1122
  this.startTimer();
1169
1123
  }
1170
- (_e = (_d = this.callbacks).onQuestionChange) == null ? void 0 : _e.call(_d, initialQ, this.getCurrentQuestionNumber(), this.getTotalQuestions());
1124
+ this.callbacks.onQuestionChange?.(initialQ, this.getCurrentQuestionNumber(), this.getTotalQuestions());
1171
1125
  }
1172
1126
  registerEvaluators() {
1173
1127
  this.evaluators.set("multiple_choice", new MultipleChoiceEvaluator());
@@ -1205,15 +1159,14 @@ var QuizEngine = class {
1205
1159
  }
1206
1160
  }
1207
1161
  handleTick() {
1208
- var _a, _b, _c, _d;
1209
1162
  if (this.timeLeftInSeconds === null) return;
1210
1163
  if (this.timeLeftInSeconds > 0) {
1211
1164
  this.timeLeftInSeconds--;
1212
- (_b = (_a = this.callbacks).onTimeTick) == null ? void 0 : _b.call(_a, this.timeLeftInSeconds);
1165
+ this.callbacks.onTimeTick?.(this.timeLeftInSeconds);
1213
1166
  }
1214
1167
  if (this.timeLeftInSeconds <= 0) {
1215
1168
  this.stopTimer();
1216
- (_d = (_c = this.callbacks).onQuizTimeUp) == null ? void 0 : _d.call(_c);
1169
+ this.callbacks.onQuizTimeUp?.();
1217
1170
  this.calculateResults();
1218
1171
  }
1219
1172
  }
@@ -1236,43 +1189,39 @@ var QuizEngine = class {
1236
1189
  return this.quizResultState.score !== void 0;
1237
1190
  }
1238
1191
  submitAnswer(questionId, answer) {
1239
- var _a, _b;
1240
1192
  this.userAnswers.set(questionId, answer);
1241
1193
  const question = this.questions.find((q) => q.id === questionId);
1242
- if (question) (_b = (_a = this.callbacks).onAnswerSubmit) == null ? void 0 : _b.call(_a, question, answer);
1194
+ if (question) this.callbacks.onAnswerSubmit?.(question, answer);
1243
1195
  }
1244
1196
  nextQuestion() {
1245
- var _a, _b;
1246
1197
  this._recordCurrentQuestionTime();
1247
1198
  if (this.currentQuestionIndex < this.questions.length - 1) {
1248
1199
  this.currentQuestionIndex++;
1249
1200
  const currentQ = this.getCurrentQuestion();
1250
1201
  this.questionStartTime = Date.now();
1251
- (_b = (_a = this.callbacks).onQuestionChange) == null ? void 0 : _b.call(_a, currentQ, this.getCurrentQuestionNumber(), this.getTotalQuestions());
1202
+ this.callbacks.onQuestionChange?.(currentQ, this.getCurrentQuestionNumber(), this.getTotalQuestions());
1252
1203
  return currentQ;
1253
1204
  }
1254
1205
  return null;
1255
1206
  }
1256
1207
  previousQuestion() {
1257
- var _a, _b;
1258
1208
  this._recordCurrentQuestionTime();
1259
1209
  if (this.currentQuestionIndex > 0) {
1260
1210
  this.currentQuestionIndex--;
1261
1211
  const currentQ = this.getCurrentQuestion();
1262
1212
  this.questionStartTime = Date.now();
1263
- (_b = (_a = this.callbacks).onQuestionChange) == null ? void 0 : _b.call(_a, currentQ, this.getCurrentQuestionNumber(), this.getTotalQuestions());
1213
+ this.callbacks.onQuestionChange?.(currentQ, this.getCurrentQuestionNumber(), this.getTotalQuestions());
1264
1214
  return currentQ;
1265
1215
  }
1266
1216
  return null;
1267
1217
  }
1268
1218
  goToQuestion(index) {
1269
- var _a, _b;
1270
1219
  if (index >= 0 && index < this.questions.length && index !== this.currentQuestionIndex) {
1271
1220
  this._recordCurrentQuestionTime();
1272
1221
  this.currentQuestionIndex = index;
1273
1222
  const currentQ = this.getCurrentQuestion();
1274
1223
  this.questionStartTime = Date.now();
1275
- (_b = (_a = this.callbacks).onQuestionChange) == null ? void 0 : _b.call(_a, currentQ, this.getCurrentQuestionNumber(), this.getTotalQuestions());
1224
+ this.callbacks.onQuestionChange?.(currentQ, this.getCurrentQuestionNumber(), this.getTotalQuestions());
1276
1225
  return currentQ;
1277
1226
  }
1278
1227
  return this.getCurrentQuestion();
@@ -1298,7 +1247,6 @@ var QuizEngine = class {
1298
1247
  }
1299
1248
  // (Tiếp theo từ Phần 1)
1300
1249
  async calculateResults() {
1301
- var _a, _b, _c, _d, _e;
1302
1250
  this.stopTimer();
1303
1251
  this._recordCurrentQuestionTime();
1304
1252
  let totalScore = 0;
@@ -1307,7 +1255,7 @@ var QuizEngine = class {
1307
1255
  let accumulatedTotalTimeSpent = 0;
1308
1256
  for (const question of this.questions) {
1309
1257
  const userAnswerRaw = this.userAnswers.get(question.id) || null;
1310
- maxScore += (_a = question.points) != null ? _a : 0;
1258
+ maxScore += question.points ?? 0;
1311
1259
  const evaluator = this.evaluators.get(question.questionType);
1312
1260
  if (!evaluator) {
1313
1261
  console.warn(`No evaluator found for question type: ${question.questionType}`);
@@ -1347,13 +1295,13 @@ var QuizEngine = class {
1347
1295
  }
1348
1296
  const percentage = maxScore > 0 ? parseFloat((totalScore / maxScore * 100).toFixed(2)) : 0;
1349
1297
  let passed = void 0;
1350
- if (((_b = this.config.settings) == null ? void 0 : _b.passingScorePercent) != null) {
1298
+ if (this.config.settings?.passingScorePercent != null) {
1351
1299
  passed = percentage >= this.config.settings.passingScorePercent;
1352
1300
  }
1353
1301
  const totalQuizTimeSpentSeconds = parseFloat(accumulatedTotalTimeSpent.toFixed(2));
1354
1302
  const averageTimePerQuestionSeconds = this.questions.length > 0 ? parseFloat((totalQuizTimeSpentSeconds / this.questions.length).toFixed(2)) : 0;
1355
1303
  const metadataPerformance = await this._calculateMetadataPerformance();
1356
- const finalResults = __spreadValues({
1304
+ const finalResults = {
1357
1305
  score: totalScore,
1358
1306
  maxScore,
1359
1307
  percentage,
@@ -1365,39 +1313,33 @@ var QuizEngine = class {
1365
1313
  scormError: this.quizResultState.scormError,
1366
1314
  studentName: this.quizResultState.studentName,
1367
1315
  totalTimeSpentSeconds: totalQuizTimeSpentSeconds,
1368
- averageTimePerQuestionSeconds
1369
- }, metadataPerformance);
1370
- this.quizResultState = __spreadValues(__spreadValues({}, this.quizResultState), finalResults);
1371
- if ((_c = this.config.settings) == null ? void 0 : _c.scorm) this._sendResultsToSCORM(finalResults);
1316
+ averageTimePerQuestionSeconds,
1317
+ ...metadataPerformance
1318
+ };
1319
+ this.quizResultState = { ...this.quizResultState, ...finalResults };
1320
+ if (this.config.settings?.scorm) this._sendResultsToSCORM(finalResults);
1372
1321
  await this._sendResultsToWebhook(finalResults);
1373
- (_e = (_d = this.callbacks).onQuizFinish) == null ? void 0 : _e.call(_d, finalResults);
1322
+ this.callbacks.onQuizFinish?.(finalResults);
1374
1323
  return finalResults;
1375
1324
  }
1376
1325
  formatUserAnswerDetail(question, userAnswerRaw) {
1377
- var _a, _b, _c, _d, _e;
1378
1326
  if (userAnswerRaw === null) return null;
1379
1327
  switch (question.questionType) {
1380
1328
  case "multiple_choice": {
1381
1329
  const q = question;
1382
1330
  const id = userAnswerRaw;
1383
- return { id, value: ((_a = q.options.find((opt) => opt.id === id)) == null ? void 0 : _a.text) || "" };
1331
+ return { id, value: q.options.find((opt) => opt.id === id)?.text || "" };
1384
1332
  }
1385
1333
  case "multiple_response": {
1386
1334
  const q = question;
1387
1335
  const ids = userAnswerRaw;
1388
- const values = ids.map((id) => {
1389
- var _a2;
1390
- return ((_a2 = q.options.find((opt) => opt.id === id)) == null ? void 0 : _a2.text) || "";
1391
- });
1336
+ const values = ids.map((id) => q.options.find((opt) => opt.id === id)?.text || "");
1392
1337
  return { id: ids, value: values };
1393
1338
  }
1394
1339
  case "sequence": {
1395
1340
  const q = question;
1396
1341
  const ids = userAnswerRaw;
1397
- const values = ids.map((id) => {
1398
- var _a2;
1399
- return ((_a2 = q.items.find((item) => item.id === id)) == null ? void 0 : _a2.content) || "";
1400
- });
1342
+ const values = ids.map((id) => q.items.find((item) => item.id === id)?.content || "");
1401
1343
  return { id: ids, value: values };
1402
1344
  }
1403
1345
  case "matching": {
@@ -1406,8 +1348,8 @@ var QuizEngine = class {
1406
1348
  const valueMap = {};
1407
1349
  for (const promptId in userAnswerMap) {
1408
1350
  const optionId = userAnswerMap[promptId];
1409
- const promptText = ((_b = q.prompts.find((p) => p.id === promptId)) == null ? void 0 : _b.content) || "";
1410
- const optionText = ((_c = q.options.find((o) => o.id === optionId)) == null ? void 0 : _c.content) || "";
1351
+ const promptText = q.prompts.find((p) => p.id === promptId)?.content || "";
1352
+ const optionText = q.options.find((o) => o.id === optionId)?.content || "";
1411
1353
  valueMap[promptText] = optionText;
1412
1354
  }
1413
1355
  return { id: null, value: valueMap };
@@ -1419,8 +1361,8 @@ var QuizEngine = class {
1419
1361
  const enrichedUserAnswerMap = {};
1420
1362
  for (const draggableId in userAnswerMapByIds) {
1421
1363
  const dropZoneId = userAnswerMapByIds[draggableId];
1422
- const draggableText = ((_d = q.draggableItems.find((d) => d.id === draggableId)) == null ? void 0 : _d.content) || `(ID: ${draggableId})`;
1423
- const dropZoneText = ((_e = q.dropZones.find((z4) => z4.id === dropZoneId)) == null ? void 0 : _e.label) || `(ID: ${dropZoneId})`;
1364
+ const draggableText = q.draggableItems.find((d) => d.id === draggableId)?.content || `(ID: ${draggableId})`;
1365
+ const dropZoneText = q.dropZones.find((z4) => z4.id === dropZoneId)?.label || `(ID: ${dropZoneId})`;
1424
1366
  enrichedUserAnswerMap[draggableText] = dropZoneText;
1425
1367
  }
1426
1368
  return { id: null, value: enrichedUserAnswerMap };
@@ -1432,7 +1374,6 @@ var QuizEngine = class {
1432
1374
  }
1433
1375
  }
1434
1376
  async _calculateMetadataPerformance() {
1435
- var _a;
1436
1377
  const loPerformanceMap = /* @__PURE__ */ new Map();
1437
1378
  const categoryPerformanceMap = /* @__PURE__ */ new Map();
1438
1379
  const topicPerformanceMap = /* @__PURE__ */ new Map();
@@ -1454,7 +1395,7 @@ var QuizEngine = class {
1454
1395
  const evaluator = this.evaluators.get(q.questionType);
1455
1396
  if (evaluator) {
1456
1397
  const { isCorrect } = await evaluator.evaluate(q, userAnswer);
1457
- const pointsForThisQuestion = (_a = q.points) != null ? _a : 0;
1398
+ const pointsForThisQuestion = q.points ?? 0;
1458
1399
  updateMap(loPerformanceMap, q.learningObjective, pointsForThisQuestion, isCorrect);
1459
1400
  updateMap(categoryPerformanceMap, q.category, pointsForThisQuestion, isCorrect);
1460
1401
  updateMap(topicPerformanceMap, q.topic, pointsForThisQuestion, isCorrect);
@@ -1481,8 +1422,7 @@ var QuizEngine = class {
1481
1422
  };
1482
1423
  }
1483
1424
  async _sendResultsToWebhook(results) {
1484
- var _a;
1485
- if (!((_a = this.config.settings) == null ? void 0 : _a.webhookUrl)) {
1425
+ if (!this.config.settings?.webhookUrl) {
1486
1426
  results.webhookStatus = "idle";
1487
1427
  return;
1488
1428
  }
@@ -1510,12 +1450,11 @@ var QuizEngine = class {
1510
1450
  }
1511
1451
  }
1512
1452
  _sendResultsToSCORM(results) {
1513
- var _a, _b, _c, _d, _e, _f, _g;
1514
1453
  if (!this.scormService || !this.scormService.hasAPI() || this.quizResultState.scormStatus === "no_api") {
1515
1454
  results.scormStatus = this.quizResultState.scormStatus || "idle";
1516
1455
  return;
1517
1456
  }
1518
- if (this.quizResultState.scormStatus === "error" && ((_a = this.quizResultState.scormError) == null ? void 0 : _a.includes("initialization failed"))) {
1457
+ if (this.quizResultState.scormStatus === "error" && this.quizResultState.scormError?.includes("initialization failed")) {
1519
1458
  results.scormStatus = "error";
1520
1459
  results.scormError = this.quizResultState.scormError;
1521
1460
  return;
@@ -1524,15 +1463,15 @@ var QuizEngine = class {
1524
1463
  try {
1525
1464
  this.scormService.setScore(results.score, results.maxScore, 0);
1526
1465
  let lessonStatusSetting = "completed";
1527
- if (((_b = this.config.settings) == null ? void 0 : _b.passingScorePercent) !== void 0 && ((_c = this.config.settings) == null ? void 0 : _c.passingScorePercent) !== null) {
1466
+ if (this.config.settings?.passingScorePercent !== void 0 && this.config.settings?.passingScorePercent !== null) {
1528
1467
  lessonStatusSetting = results.passed ? "passed" : "failed";
1529
- } else if ((_e = (_d = this.config.settings) == null ? void 0 : _d.scorm) == null ? void 0 : _e.setCompletionOnFinish) {
1468
+ } else if (this.config.settings?.scorm?.setCompletionOnFinish) {
1530
1469
  lessonStatusSetting = "completed";
1531
1470
  }
1532
1471
  this.scormService.setLessonStatus(lessonStatusSetting, results.passed);
1533
1472
  if (results.totalTimeSpentSeconds !== void 0 && this.scormService.formatCMITime) {
1534
1473
  const cmiTime = this.scormService.formatCMITime(results.totalTimeSpentSeconds);
1535
- const sessionTimeVar = ((_g = (_f = this.config.settings) == null ? void 0 : _f.scorm) == null ? void 0 : _g.sessionTimeVar) || (this.scormService.getSCORMVersion() === "2004" ? "cmi.session_time" : "cmi.core.session_time");
1474
+ const sessionTimeVar = this.config.settings?.scorm?.sessionTimeVar || (this.scormService.getSCORMVersion() === "2004" ? "cmi.session_time" : "cmi.core.session_time");
1536
1475
  if (sessionTimeVar) this.scormService.setValue(sessionTimeVar, cmiTime);
1537
1476
  }
1538
1477
  const commitResult = this.scormService.commit();
@@ -1572,18 +1511,19 @@ var QuizEditorService = class {
1572
1511
  };
1573
1512
  switch (type) {
1574
1513
  case "true_false":
1575
- return __spreadProps(__spreadValues({}, baseNewQuestion), { questionType: "true_false", correctAnswer: true });
1514
+ return { ...baseNewQuestion, questionType: "true_false", correctAnswer: true };
1576
1515
  case "multiple_choice":
1577
- return __spreadProps(__spreadValues({}, baseNewQuestion), { questionType: "multiple_choice", options: [], correctAnswerId: "" });
1516
+ return { ...baseNewQuestion, questionType: "multiple_choice", options: [], correctAnswerId: "" };
1578
1517
  case "multiple_response":
1579
- return __spreadProps(__spreadValues({}, baseNewQuestion), { questionType: "multiple_response", options: [], correctAnswerIds: [] });
1518
+ return { ...baseNewQuestion, questionType: "multiple_response", options: [], correctAnswerIds: [] };
1580
1519
  case "short_answer":
1581
- return __spreadProps(__spreadValues({}, baseNewQuestion), { questionType: "short_answer", acceptedAnswers: [""], isCaseSensitive: false });
1520
+ return { ...baseNewQuestion, questionType: "short_answer", acceptedAnswers: [""], isCaseSensitive: false };
1582
1521
  case "numeric":
1583
- return __spreadProps(__spreadValues({}, baseNewQuestion), { questionType: "numeric", answer: 0 });
1522
+ return { ...baseNewQuestion, questionType: "numeric", answer: 0 };
1584
1523
  case "fill_in_the_blanks": {
1585
1524
  const blankId = generateUniqueId("blank_");
1586
- return __spreadProps(__spreadValues({}, baseNewQuestion), {
1525
+ return {
1526
+ ...baseNewQuestion,
1587
1527
  questionType: "fill_in_the_blanks",
1588
1528
  segments: [
1589
1529
  { type: "text", content: "Your text before " },
@@ -1592,49 +1532,52 @@ var QuizEditorService = class {
1592
1532
  ],
1593
1533
  answers: [{ blankId, acceptedValues: [""] }],
1594
1534
  isCaseSensitive: false
1595
- });
1535
+ };
1596
1536
  }
1597
1537
  case "sequence":
1598
- return __spreadProps(__spreadValues({}, baseNewQuestion), { questionType: "sequence", items: [], correctOrder: [] });
1538
+ return { ...baseNewQuestion, questionType: "sequence", items: [], correctOrder: [] };
1599
1539
  case "matching":
1600
- return __spreadProps(__spreadValues({}, baseNewQuestion), { questionType: "matching", prompts: [], options: [], correctAnswerMap: [], shuffleOptions: true });
1540
+ return { ...baseNewQuestion, questionType: "matching", prompts: [], options: [], correctAnswerMap: [], shuffleOptions: true };
1601
1541
  case "drag_and_drop":
1602
- return __spreadProps(__spreadValues({}, baseNewQuestion), { questionType: "drag_and_drop", draggableItems: [], dropZones: [], answerMap: [] });
1542
+ return { ...baseNewQuestion, questionType: "drag_and_drop", draggableItems: [], dropZones: [], answerMap: [] };
1603
1543
  case "hotspot":
1604
- return __spreadProps(__spreadValues({}, baseNewQuestion), { questionType: "hotspot", imageUrl: "", hotspots: [], correctHotspotIds: [] });
1544
+ return { ...baseNewQuestion, questionType: "hotspot", imageUrl: "", hotspots: [], correctHotspotIds: [] };
1605
1545
  case "blockly_programming":
1606
- return __spreadProps(__spreadValues({}, baseNewQuestion), {
1546
+ return {
1547
+ ...baseNewQuestion,
1607
1548
  questionType: "blockly_programming",
1608
1549
  toolboxDefinition: '<xml xmlns="https://developers.google.com/blockly/xml"></xml>',
1609
1550
  initialWorkspace: "",
1610
1551
  solutionWorkspaceXML: "",
1611
1552
  solutionGeneratedCode: ""
1612
- });
1553
+ };
1613
1554
  case "scratch_programming":
1614
- return __spreadProps(__spreadValues({}, baseNewQuestion), {
1555
+ return {
1556
+ ...baseNewQuestion,
1615
1557
  questionType: "scratch_programming",
1616
1558
  toolboxDefinition: '<xml xmlns="https://developers.google.com/blockly/xml"></xml>',
1617
1559
  initialWorkspace: "",
1618
1560
  solutionWorkspaceXML: "",
1619
1561
  solutionGeneratedCode: ""
1620
- });
1562
+ };
1621
1563
  case "coding":
1622
- return __spreadProps(__spreadValues({}, baseNewQuestion), {
1564
+ return {
1565
+ ...baseNewQuestion,
1623
1566
  questionType: "coding",
1624
- language: "javascript",
1567
+ codingLanguage: "javascript",
1625
1568
  solutionCode: "",
1626
1569
  testCases: [],
1627
1570
  functionSignature: "",
1628
1571
  points: 25
1629
1572
  // Coding questions are worth more by default
1630
- });
1573
+ };
1631
1574
  default:
1632
1575
  const _exhaustiveCheck = type;
1633
1576
  throw new Error(`Question type "${_exhaustiveCheck}" is not supported for creation.`);
1634
1577
  }
1635
1578
  }
1636
1579
  addQuestion(question) {
1637
- const newQuestion = __spreadValues({}, question);
1580
+ const newQuestion = { ...question };
1638
1581
  if (newQuestion.id.startsWith("new_")) {
1639
1582
  newQuestion.id = generateUniqueId(`${newQuestion.questionType}_`);
1640
1583
  }
@@ -1748,8 +1691,7 @@ var QuestionImportService = class {
1748
1691
  const values = line.split(" ");
1749
1692
  const rowObject = {};
1750
1693
  header.forEach((h, i) => {
1751
- var _a;
1752
- rowObject[h] = ((_a = values[i]) == null ? void 0 : _a.trim()) || "";
1694
+ rowObject[h] = values[i]?.trim() || "";
1753
1695
  });
1754
1696
  try {
1755
1697
  const transformedObject = this.transformTsvRowToRawObject(rowObject);
@@ -1791,17 +1733,17 @@ var QuestionImportService = class {
1791
1733
  };
1792
1734
  switch (questionType) {
1793
1735
  case "multiple_choice":
1794
- return __spreadProps(__spreadValues({}, base), { options: options.split("|"), correctAnswer });
1736
+ return { ...base, options: options.split("|"), correctAnswer };
1795
1737
  case "multiple_response":
1796
- return __spreadProps(__spreadValues({}, base), { options: options.split("|"), correctAnswers: correctAnswer.split("|") });
1738
+ return { ...base, options: options.split("|"), correctAnswers: correctAnswer.split("|") };
1797
1739
  case "true_false":
1798
- return __spreadProps(__spreadValues({}, base), { correctAnswer: correctAnswer.toLowerCase() === "true" });
1740
+ return { ...base, correctAnswer: correctAnswer.toLowerCase() === "true" };
1799
1741
  case "short_answer":
1800
- return __spreadProps(__spreadValues({}, base), { acceptedAnswers: correctAnswer.split("|") });
1742
+ return { ...base, acceptedAnswers: correctAnswer.split("|") };
1801
1743
  case "numeric":
1802
- return __spreadProps(__spreadValues({}, base), { answer: parseFloat(correctAnswer), tolerance: tolerance ? parseFloat(tolerance) : void 0 });
1744
+ return { ...base, answer: parseFloat(correctAnswer), tolerance: tolerance ? parseFloat(tolerance) : void 0 };
1803
1745
  case "sequence":
1804
- return __spreadProps(__spreadValues({}, base), { items: options.split("|"), correctOrder: correctAnswer.split("|") });
1746
+ return { ...base, items: options.split("|"), correctOrder: correctAnswer.split("|") };
1805
1747
  case "matching": {
1806
1748
  const [promptsStr, optionsStr] = options.split("#");
1807
1749
  const prompts = promptsStr.replace("prompts:", "").split("|");
@@ -1811,7 +1753,7 @@ var QuestionImportService = class {
1811
1753
  acc[key] = valParts.join(":");
1812
1754
  return acc;
1813
1755
  }, {});
1814
- return __spreadProps(__spreadValues({}, base), { prompts, options: opts, correctAnswerMap });
1756
+ return { ...base, prompts, options: opts, correctAnswerMap };
1815
1757
  }
1816
1758
  case "fill_in_the_blanks": {
1817
1759
  const blanks = correctAnswer.split("#").reduce((acc, part) => {
@@ -1819,7 +1761,7 @@ var QuestionImportService = class {
1819
1761
  acc[key] = valuesStr.split("|");
1820
1762
  return acc;
1821
1763
  }, {});
1822
- return __spreadProps(__spreadValues({}, base), { sentenceWithPlaceholders: options, blanks });
1764
+ return { ...base, sentenceWithPlaceholders: options, blanks };
1823
1765
  }
1824
1766
  default:
1825
1767
  throw new Error(`Unsupported questionType "${questionType}" in TSV.`);
@@ -1840,20 +1782,20 @@ var QuestionImportService = class {
1840
1782
  const options = validatedRawQ.options.map((text) => ({ id: generateUniqueId("opt_"), text }));
1841
1783
  const correctOption = options.find((opt) => opt.text === validatedRawQ.correctAnswer);
1842
1784
  if (!correctOption) throw new Error(`Correct answer "${validatedRawQ.correctAnswer}" not found in options.`);
1843
- return __spreadProps(__spreadValues({}, baseQuestionData), { questionType: "multiple_choice", options, correctAnswerId: correctOption.id });
1785
+ return { ...baseQuestionData, questionType: "multiple_choice", options, correctAnswerId: correctOption.id };
1844
1786
  }
1845
1787
  case "multiple_response": {
1846
1788
  const options = validatedRawQ.options.map((text) => ({ id: generateUniqueId("opt_mr_"), text }));
1847
1789
  const correctIds = options.filter((opt) => validatedRawQ.correctAnswers.includes(opt.text)).map((opt) => opt.id);
1848
1790
  if (correctIds.length !== validatedRawQ.correctAnswers.length) throw new Error("Some correct answers were not found in options.");
1849
- return __spreadProps(__spreadValues({}, baseQuestionData), { questionType: "multiple_response", options, correctAnswerIds: correctIds });
1791
+ return { ...baseQuestionData, questionType: "multiple_response", options, correctAnswerIds: correctIds };
1850
1792
  }
1851
1793
  case "true_false":
1852
- return __spreadProps(__spreadValues({}, baseQuestionData), { questionType: "true_false", correctAnswer: validatedRawQ.correctAnswer });
1794
+ return { ...baseQuestionData, questionType: "true_false", correctAnswer: validatedRawQ.correctAnswer };
1853
1795
  case "short_answer":
1854
- return __spreadProps(__spreadValues({}, baseQuestionData), { questionType: "short_answer", acceptedAnswers: validatedRawQ.acceptedAnswers, isCaseSensitive: false });
1796
+ return { ...baseQuestionData, questionType: "short_answer", acceptedAnswers: validatedRawQ.acceptedAnswers, isCaseSensitive: false };
1855
1797
  case "numeric":
1856
- return __spreadProps(__spreadValues({}, baseQuestionData), { questionType: "numeric", answer: validatedRawQ.answer, tolerance: validatedRawQ.tolerance });
1798
+ return { ...baseQuestionData, questionType: "numeric", answer: validatedRawQ.answer, tolerance: validatedRawQ.tolerance };
1857
1799
  case "sequence": {
1858
1800
  if (validatedRawQ.items.length !== validatedRawQ.correctOrder.length) {
1859
1801
  throw new Error("The number of items must match the number of items in the correct order for a sequence question.");
@@ -1864,7 +1806,7 @@ var QuestionImportService = class {
1864
1806
  if (!foundItem) throw new Error(`Sequence item "${orderText}" in correctOrder not found in items list.`);
1865
1807
  return foundItem.id;
1866
1808
  });
1867
- return __spreadProps(__spreadValues({}, baseQuestionData), { questionType: "sequence", items, correctOrder });
1809
+ return { ...baseQuestionData, questionType: "sequence", items, correctOrder };
1868
1810
  }
1869
1811
  case "matching": {
1870
1812
  if (validatedRawQ.prompts.length !== Object.keys(validatedRawQ.correctAnswerMap).length) {
@@ -1878,7 +1820,7 @@ var QuestionImportService = class {
1878
1820
  if (!prompt || !option) throw new Error(`Matching pair "${promptText}":"${optionText}" not found in prompts/options.`);
1879
1821
  return { promptId: prompt.id, optionId: option.id };
1880
1822
  });
1881
- return __spreadProps(__spreadValues({}, baseQuestionData), { questionType: "matching", prompts, options, correctAnswerMap, shuffleOptions: true });
1823
+ return { ...baseQuestionData, questionType: "matching", prompts, options, correctAnswerMap, shuffleOptions: true };
1882
1824
  }
1883
1825
  case "fill_in_the_blanks": {
1884
1826
  const { sentenceWithPlaceholders, blanks } = validatedRawQ;
@@ -1906,7 +1848,7 @@ var QuestionImportService = class {
1906
1848
  if (lastIndex < sentenceWithPlaceholders.length) {
1907
1849
  segments.push({ type: "text", content: sentenceWithPlaceholders.substring(lastIndex) });
1908
1850
  }
1909
- return __spreadProps(__spreadValues({}, baseQuestionData), { questionType: "fill_in_the_blanks", segments, answers, isCaseSensitive: false });
1851
+ return { ...baseQuestionData, questionType: "fill_in_the_blanks", segments, answers, isCaseSensitive: false };
1910
1852
  }
1911
1853
  }
1912
1854
  throw new Error(`Unhandled question type in createQuestionFromRawObject: ${validatedRawQ.questionType}`);
@@ -1967,8 +1909,7 @@ var UserConfigService = class {
1967
1909
  this.setConfig("weeklyGoal", goal);
1968
1910
  }
1969
1911
  static getLanguage() {
1970
- var _a;
1971
- return (_a = this.getConfig("language", "en")) != null ? _a : "en";
1912
+ return this.getConfig("language", "en") ?? "en";
1972
1913
  }
1973
1914
  static setLanguage(language) {
1974
1915
  this.setConfig("language", language);
@@ -1986,10 +1927,11 @@ var UserConfigService = class {
1986
1927
  */
1987
1928
  static addGoal(newGoal) {
1988
1929
  const goals = this.getGoals();
1989
- const goalToAdd = __spreadProps(__spreadValues({}, newGoal), {
1930
+ const goalToAdd = {
1931
+ ...newGoal,
1990
1932
  id: generateUniqueId("goal_"),
1991
1933
  isAchieved: false
1992
- });
1934
+ };
1993
1935
  this.saveGoals([...goals, goalToAdd]);
1994
1936
  }
1995
1937
  static updateGoal(updatedGoal) {
@@ -2650,7 +2592,7 @@ var LocalStorageManager = class {
2650
2592
  if (items.some((i) => i.code === item.code)) {
2651
2593
  throw new Error(`An item with code "${item.code}" already exists for ${this.key}.`);
2652
2594
  }
2653
- const newItem = __spreadProps(__spreadValues({}, item), { id: generateUniqueId(`${this.key}_`) });
2595
+ const newItem = { ...item, id: generateUniqueId(`${this.key}_`) };
2654
2596
  this.saveAll([...items, newItem]);
2655
2597
  return newItem;
2656
2598
  }
@@ -2663,7 +2605,7 @@ var LocalStorageManager = class {
2663
2605
  console.warn(`Item with id "${id}" not found in ${this.key} for update.`);
2664
2606
  return null;
2665
2607
  }
2666
- const updatedItem = __spreadValues(__spreadValues({}, items[index]), updates);
2608
+ const updatedItem = { ...items[index], ...updates };
2667
2609
  items[index] = updatedItem;
2668
2610
  this.saveAll(items);
2669
2611
  return updatedItem;
@@ -2757,10 +2699,10 @@ _MetadataService.deleteContext = (code) => contextManager.delete(code);
2757
2699
  _MetadataService.getApproaches = () => approachManager.getAll().sort((a, b) => a.code.localeCompare(b.code));
2758
2700
  _MetadataService.addApproach = (approachData) => {
2759
2701
  const difficulty = mapRawDifficultyToStandard(approachData.rawDifficulty);
2760
- return approachManager.add(__spreadProps(__spreadValues({}, approachData), { difficulty }));
2702
+ return approachManager.add({ ...approachData, difficulty });
2761
2703
  };
2762
2704
  _MetadataService.updateApproach = (id, approachData) => {
2763
- const updates = __spreadValues({}, approachData);
2705
+ const updates = { ...approachData };
2764
2706
  if (approachData.rawDifficulty) {
2765
2707
  updates.difficulty = mapRawDifficultyToStandard(approachData.rawDifficulty);
2766
2708
  }
@@ -2843,10 +2785,11 @@ var QuestionBankService = class {
2843
2785
  if (allQuestions.some((q) => q.code === questionData.code)) {
2844
2786
  throw new Error(`A question with code "${questionData.code}" already exists.`);
2845
2787
  }
2846
- const newQuestion = __spreadProps(__spreadValues({}, questionData), {
2788
+ const newQuestion = {
2789
+ ...questionData,
2847
2790
  id: generateUniqueId("qb_"),
2848
2791
  lastModified: (/* @__PURE__ */ new Date()).toISOString()
2849
- });
2792
+ };
2850
2793
  questionBankManager.saveAll([...allQuestions, newQuestion]);
2851
2794
  return newQuestion;
2852
2795
  }
@@ -2858,9 +2801,11 @@ var QuestionBankService = class {
2858
2801
  console.warn(`Question with id "${id}" not found for update.`);
2859
2802
  return null;
2860
2803
  }
2861
- const updatedQuestion = __spreadProps(__spreadValues(__spreadValues({}, allQuestions[index]), updates), {
2804
+ const updatedQuestion = {
2805
+ ...allQuestions[index],
2806
+ ...updates,
2862
2807
  lastModified: (/* @__PURE__ */ new Date()).toISOString()
2863
- });
2808
+ };
2864
2809
  allQuestions[index] = updatedQuestion;
2865
2810
  questionBankManager.saveAll(allQuestions);
2866
2811
  return updatedQuestion;
@@ -3008,13 +2953,12 @@ var escapeXML = (unsafe) => {
3008
2953
  });
3009
2954
  };
3010
2955
  var generateSCORMManifest = (quizConfig, scormVersion, launcherFile = "index.html", libraryJSPath = "scorm-bundle/player.js", quizDataPath = "quiz_data.json", blocklyCSSPath = "blockly-styles.css", mainCSSPath = "styles.css") => {
3011
- var _a;
3012
2956
  const uniqueId = `iqk_${quizConfig.id.replace(/[^a-zA-Z0-9_]/g, "_")}`;
3013
2957
  const organizationId = `ORG-${uniqueId}`;
3014
2958
  const itemId = `ITEM-${uniqueId}`;
3015
2959
  const resourceId = `RES-${uniqueId}`;
3016
2960
  const quizTitle = escapeXML(quizConfig.title);
3017
- const passingScore = (_a = quizConfig.settings) == null ? void 0 : _a.passingScorePercent;
2961
+ const passingScore = quizConfig.settings?.passingScorePercent;
3018
2962
  const effectiveScormVersion = scormVersion;
3019
2963
  const schemaVersion = effectiveScormVersion === "2004" ? "2004 4th Edition" : "1.2";
3020
2964
  const adlcpNamespace = effectiveScormVersion === "2004" ? "http://www.adlnet.org/xsd/adlcp_v1p3" : "http://www.adlnet.org/xsd/adlcp_rootv1p2";