@pie-element/categorize 11.0.1-next.0 → 11.0.1

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.
@@ -0,0 +1,509 @@
1
+ import isEmpty from 'lodash/isEmpty';
2
+ import { buildState } from '@pie-lib/categorize';
3
+ export { score } from '@pie-lib/categorize';
4
+ import { getFeedbackForCorrectness } from '@pie-lib/feedback';
5
+ import { partialScoring, lockChoices, getShuffledChoices } from '@pie-lib/controller-utils';
6
+ import Translator from '@pie-lib/translator';
7
+
8
+ function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
9
+ try {
10
+ var info = gen[key](arg);
11
+ var value = info.value;
12
+ } catch (error) {
13
+ reject(error);
14
+ return;
15
+ }
16
+
17
+ if (info.done) {
18
+ resolve(value);
19
+ } else {
20
+ Promise.resolve(value).then(_next, _throw);
21
+ }
22
+ }
23
+
24
+ function _asyncToGenerator(fn) {
25
+ return function () {
26
+ var self = this,
27
+ args = arguments;
28
+ return new Promise(function (resolve, reject) {
29
+ var gen = fn.apply(self, args);
30
+
31
+ function _next(value) {
32
+ asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
33
+ }
34
+
35
+ function _throw(err) {
36
+ asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
37
+ }
38
+
39
+ _next(undefined);
40
+ });
41
+ };
42
+ }
43
+
44
+ function _defineProperty(obj, key, value) {
45
+ if (key in obj) {
46
+ Object.defineProperty(obj, key, {
47
+ value: value,
48
+ enumerable: true,
49
+ configurable: true,
50
+ writable: true
51
+ });
52
+ } else {
53
+ obj[key] = value;
54
+ }
55
+
56
+ return obj;
57
+ }
58
+
59
+ // used in configure too, for consistency modify it there too
60
+ var multiplePlacements = {
61
+ enabled: 'Yes',
62
+ disabled: 'No',
63
+ perChoice: 'Set Per Choice'
64
+ }; // used to validate the config
65
+
66
+ var isCorrectResponseDuplicated = (choices, alternate) => {
67
+ if (choices.length < 1 || alternate.length < 1) {
68
+ return -1;
69
+ }
70
+
71
+ var stringChoices = JSON.stringify(choices.sort());
72
+ var stringAlternate = alternate.reduce((total, current) => current.length > 0 ? [...total, JSON.stringify(current.sort())] : total, []);
73
+ var foundIndexDuplicate = stringAlternate.findIndex(alternate => alternate.length && alternate === stringChoices);
74
+ return foundIndexDuplicate;
75
+ };
76
+ var isAlternateDuplicated = alternate => {
77
+ if (alternate.length <= 1) {
78
+ return -1;
79
+ }
80
+
81
+ var elementSet = new Set();
82
+ var stringAlternate = alternate.reduce((total, current) => current.length > 0 ? [...total, JSON.stringify(current.sort())] : total, []);
83
+
84
+ for (var i = 0; i < stringAlternate.length; i++) {
85
+ if (elementSet.has(stringAlternate[i]) && stringAlternate[i]) {
86
+ return i;
87
+ }
88
+
89
+ elementSet.add(stringAlternate[i]);
90
+ }
91
+
92
+ return -1;
93
+ };
94
+
95
+ var defaults = {
96
+ allowMultiplePlacementsEnabled: multiplePlacements.enabled,
97
+ alternates: [],
98
+ categories: [],
99
+ categoriesPerRow: 2,
100
+ choices: [],
101
+ choicesLabel: '',
102
+ choicesPosition: 'below',
103
+ correctResponse: [],
104
+ feedbackEnabled: false,
105
+ lockChoiceOrder: true,
106
+ maxAnswerChoices: 6,
107
+ maxChoicesPerCategory: 0,
108
+ partialScoring: true,
109
+ prompt: '',
110
+ promptEnabled: true,
111
+ rationale: '',
112
+ rationaleEnabled: true,
113
+ rowLabels: [''],
114
+ studentInstructionsEnabled: true,
115
+ teacherInstructions: '',
116
+ teacherInstructionsEnabled: true,
117
+ toolbarEditorPosition: 'bottom',
118
+ minRowHeight: '80px'
119
+ };
120
+
121
+ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
122
+
123
+ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
124
+ var {
125
+ translator
126
+ } = Translator;
127
+ var getPartialScore = (correctResponse, builtCategories) => {
128
+ // in the resulted best scenario we make a sum with all the correct responses
129
+ // and all the placements
130
+ var {
131
+ placements,
132
+ score
133
+ } = builtCategories.reduce((acc, _ref) => {
134
+ var {
135
+ choices = []
136
+ } = _ref;
137
+ return {
138
+ placements: acc.placements + choices.length,
139
+ score: acc.score + choices.filter(ch => ch.correct).length
140
+ };
141
+ }, {
142
+ placements: 0,
143
+ score: 0
144
+ }); // in the correct response, we make a sum of the max possible score
145
+
146
+ var {
147
+ maxScore
148
+ } = correctResponse.reduce((acc, _ref2) => {
149
+ var {
150
+ choices
151
+ } = _ref2;
152
+ return {
153
+ maxScore: acc.maxScore + choices.length
154
+ };
155
+ }, {
156
+ maxScore: 0
157
+ }); // if there are any extra placements, we subtract from the obtained score
158
+
159
+ var extraPlacements = placements > maxScore ? placements - maxScore : 0;
160
+ var totalScore = (score - extraPlacements) / maxScore;
161
+ return totalScore < 0 ? 0 : parseFloat(totalScore.toFixed(2));
162
+ };
163
+
164
+ var getAlternates = correctResponse => correctResponse.map(c => c.alternateResponses).filter(alternate => alternate);
165
+
166
+ var getTotalScore = (question, session, env) => {
167
+ if (!session) {
168
+ return 0;
169
+ }
170
+
171
+ if (Object.keys(session).length === 0) {
172
+ return 0;
173
+ }
174
+
175
+ var {
176
+ categories,
177
+ choices
178
+ } = question || {};
179
+ var {
180
+ correctResponse
181
+ } = question || {};
182
+ var {
183
+ answers
184
+ } = session || {};
185
+ answers = answers || [];
186
+ correctResponse = correctResponse || []; // this function is used in pie-ui/categorize as well, in order to get the best scenario
187
+ // so we get the best scenario and calculate the score
188
+
189
+ var {
190
+ categories: builtCategories,
191
+ correct
192
+ } = buildState(categories, choices, answers, correctResponse);
193
+ var alternates = getAlternates(correctResponse);
194
+ var enabled = partialScoring.enabled(question, env); // if there are any alternates, there will be no partial scoring!
195
+
196
+ if (enabled && !alternates.length) {
197
+ // we apply partial scoring
198
+ return getPartialScore(correctResponse, builtCategories);
199
+ } // else we apply dichotomous
200
+
201
+
202
+ return correct ? 1 : 0;
203
+ };
204
+ var getCorrectness = (question, session, env) => {
205
+ return new Promise(resolve => {
206
+ if (env.mode === 'evaluate') {
207
+ var _score = getTotalScore(question, session, env);
208
+
209
+ if (_score === 1) {
210
+ resolve('correct');
211
+ } else if (_score === 0) {
212
+ resolve('incorrect');
213
+ } else {
214
+ resolve('partially-correct');
215
+ }
216
+ } else {
217
+ resolve(undefined);
218
+ }
219
+ });
220
+ };
221
+ var createDefaultModel = function createDefaultModel() {
222
+ var model = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
223
+ return new Promise(resolve => {
224
+ resolve(_objectSpread(_objectSpread({}, defaults), model));
225
+ });
226
+ };
227
+ var normalize = question => _objectSpread(_objectSpread({}, defaults), question);
228
+ /**
229
+ *
230
+ * @param {*} question
231
+ * @param {*} session
232
+ * @param {*} env
233
+ * @param {*} updateSession - optional - a function that will set the properties passed into it on the session.
234
+ */
235
+
236
+ var model = (question, session, env, updateSession) => new Promise( /*#__PURE__*/function () {
237
+ var _ref3 = _asyncToGenerator(function* (resolve) {
238
+ var normalizedQuestion = normalize(question);
239
+ var answerCorrectness = yield getCorrectness(normalizedQuestion, session, env);
240
+ var {
241
+ mode,
242
+ role
243
+ } = env || {};
244
+ var {
245
+ categories,
246
+ categoriesPerRow,
247
+ choicesLabel,
248
+ choicesPosition,
249
+ correctResponse,
250
+ feedback,
251
+ feedbackEnabled,
252
+ promptEnabled,
253
+ prompt,
254
+ rowLabels,
255
+ rationaleEnabled,
256
+ rationale,
257
+ teacherInstructionsEnabled,
258
+ teacherInstructions,
259
+ language,
260
+ maxChoicesPerCategory,
261
+ extraCSSRules,
262
+ minRowHeight,
263
+ fontSizeFactor,
264
+ autoplayAudioEnabled,
265
+ completeAudioEnabled,
266
+ customAudioButton
267
+ } = normalizedQuestion;
268
+ var {
269
+ choices,
270
+ note
271
+ } = normalizedQuestion;
272
+ var fb;
273
+ var lockChoiceOrder = lockChoices(normalizedQuestion, session, env);
274
+ var filteredCorrectResponse = correctResponse.map(response => {
275
+ var filteredChoices = (response.choices || []).filter(choice => choice !== 'null');
276
+ return _objectSpread(_objectSpread({}, response), {}, {
277
+ choices: filteredChoices
278
+ });
279
+ });
280
+
281
+ if (mode === 'evaluate' && feedbackEnabled) {
282
+ fb = yield getFeedbackForCorrectness(answerCorrectness, feedback);
283
+ }
284
+
285
+ if (!lockChoiceOrder) {
286
+ choices = yield getShuffledChoices(choices, session, updateSession, 'id');
287
+ }
288
+
289
+ if (!note) {
290
+ note = translator.t('common:commonCorrectAnswerWithAlternates', {
291
+ lng: language
292
+ });
293
+ }
294
+
295
+ var alternates = getAlternates(filteredCorrectResponse);
296
+ var out = {
297
+ categories: categories || [],
298
+ categoriesPerRow: categoriesPerRow || 2,
299
+ maxChoicesPerCategory,
300
+ correctness: answerCorrectness,
301
+ choices: choices || [],
302
+ choicesLabel: choicesLabel || '',
303
+ choicesPosition,
304
+ disabled: mode !== 'gather',
305
+ feedback: fb,
306
+ lockChoiceOrder,
307
+ prompt: promptEnabled ? prompt : null,
308
+ rowLabels,
309
+ note,
310
+ env,
311
+ showNote: alternates && alternates.length > 0,
312
+ correctResponse: mode === 'evaluate' ? filteredCorrectResponse : undefined,
313
+ language,
314
+ extraCSSRules,
315
+ fontSizeFactor,
316
+ minRowHeight: minRowHeight,
317
+ autoplayAudioEnabled,
318
+ completeAudioEnabled,
319
+ customAudioButton
320
+ };
321
+
322
+ if (role === 'instructor' && (mode === 'view' || mode === 'evaluate')) {
323
+ out.rationale = rationaleEnabled ? rationale : null;
324
+ out.teacherInstructions = teacherInstructionsEnabled ? teacherInstructions : null;
325
+ } else {
326
+ out.rationale = null;
327
+ out.teacherInstructions = null;
328
+ }
329
+
330
+ resolve(out);
331
+ });
332
+
333
+ return function (_x) {
334
+ return _ref3.apply(this, arguments);
335
+ };
336
+ }());
337
+ var outcome = (question, session, env) => {
338
+ if (env.mode !== 'evaluate') {
339
+ return Promise.reject(new Error('Can not call outcome when mode is not evaluate'));
340
+ } else {
341
+ return new Promise(resolve => {
342
+ resolve({
343
+ score: getTotalScore(question, session, env),
344
+ empty: !session || isEmpty(session)
345
+ });
346
+ });
347
+ }
348
+ };
349
+ var createCorrectResponseSession = (question, env) => {
350
+ return new Promise(resolve => {
351
+ var {
352
+ mode,
353
+ role
354
+ } = env || {};
355
+
356
+ if (mode !== 'evaluate' && role === 'instructor') {
357
+ var {
358
+ correctResponse
359
+ } = question;
360
+ resolve({
361
+ answers: correctResponse,
362
+ id: 1
363
+ });
364
+ } else {
365
+ return resolve(null);
366
+ }
367
+ });
368
+ }; // remove all html tags
369
+
370
+ var getInnerText = html => (html || '').replaceAll(/<[^>]*>/g, ''); // remove all html tags except img, iframe and source tag for audio
371
+
372
+
373
+ var getContent = html => (html || '').replace(/(<(?!img|iframe|source)([^>]+)>)/gi, '');
374
+
375
+ var validate = function validate() {
376
+ var model = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
377
+ var config = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
378
+ var {
379
+ categories,
380
+ choices,
381
+ correctResponse,
382
+ maxAnswerChoices
383
+ } = model;
384
+ var {
385
+ minChoices = 1,
386
+ minCategories = 1,
387
+ maxCategories = 12,
388
+ maxLengthPerChoice = 300,
389
+ maxLengthPerCategory = 150
390
+ } = config;
391
+ var reversedChoices = [...(choices || [])].reverse();
392
+ var errors = {};
393
+ var choicesErrors = {};
394
+ var categoriesErrors = {};
395
+ ['teacherInstructions', 'prompt', 'rationale'].forEach(field => {
396
+ var _config$field;
397
+
398
+ if ((_config$field = config[field]) !== null && _config$field !== void 0 && _config$field.required && !getContent(model[field])) {
399
+ errors[field] = 'This field is required.';
400
+ }
401
+ });
402
+ (categories || []).forEach(category => {
403
+ var {
404
+ id,
405
+ label
406
+ } = category;
407
+
408
+ if (getInnerText(label).length > maxLengthPerCategory) {
409
+ categoriesErrors[id] = "Category labels should be no more than ".concat(maxLengthPerCategory, " characters long.");
410
+ }
411
+ });
412
+ (reversedChoices || []).forEach((choice, index) => {
413
+ var {
414
+ id,
415
+ content
416
+ } = choice;
417
+
418
+ if (getInnerText(content).length > maxLengthPerChoice) {
419
+ choicesErrors[id] = "Tokens should be no more than ".concat(maxLengthPerChoice, " characters long.");
420
+ }
421
+
422
+ if (!getContent(content)) {
423
+ choicesErrors[id] = 'Tokens should not be empty.';
424
+ } else {
425
+ var identicalAnswer = reversedChoices.slice(index + 1).some(c => c.content === content);
426
+
427
+ if (identicalAnswer) {
428
+ choicesErrors[id] = 'Tokens content should be unique.';
429
+ }
430
+ }
431
+ });
432
+ var nbOfCategories = (categories || []).length;
433
+ var nbOfChoices = (choices || []).length;
434
+
435
+ if (nbOfCategories > maxCategories) {
436
+ errors.categoriesError = "No more than ".concat(maxCategories, " categories should be defined.");
437
+ } else if (nbOfCategories < minCategories) {
438
+ errors.categoriesError = "There should be at least ".concat(minCategories, " category defined.");
439
+ }
440
+
441
+ if (nbOfChoices < minChoices) {
442
+ errors.choicesError = "There should be at least ".concat(minChoices, " choices defined.");
443
+ } else if (nbOfChoices > maxAnswerChoices) {
444
+ errors.choicesError = "No more than ".concat(maxAnswerChoices, " choices should be defined.");
445
+ }
446
+
447
+ if (nbOfChoices && nbOfCategories) {
448
+ var hasAssociations = false;
449
+ (correctResponse || []).forEach(response => {
450
+ var {
451
+ choices = [],
452
+ alternateResponses = []
453
+ } = response;
454
+
455
+ if (choices.length) {
456
+ hasAssociations = true;
457
+ } else {
458
+ alternateResponses.forEach(alternate => {
459
+ if ((alternate || []).length) {
460
+ hasAssociations = true;
461
+ }
462
+ });
463
+ }
464
+ });
465
+ var duplicateAlternateIndex = -1;
466
+ var duplicateCategory = '';
467
+ (correctResponse || []).forEach(response => {
468
+ var {
469
+ choices = [],
470
+ alternateResponses = [],
471
+ category
472
+ } = response;
473
+
474
+ if (duplicateAlternateIndex === -1) {
475
+ duplicateAlternateIndex = isCorrectResponseDuplicated(choices, alternateResponses);
476
+
477
+ if (duplicateAlternateIndex === -1) {
478
+ duplicateAlternateIndex = isAlternateDuplicated(alternateResponses);
479
+ }
480
+
481
+ duplicateCategory = category;
482
+ }
483
+ });
484
+
485
+ if (duplicateAlternateIndex > -1) {
486
+ errors.duplicateAlternate = {
487
+ index: duplicateAlternateIndex,
488
+ category: duplicateCategory
489
+ };
490
+ }
491
+
492
+ if (!hasAssociations) {
493
+ errors.associationError = 'At least one token should be assigned to at least one category.';
494
+ }
495
+ }
496
+
497
+ if (!isEmpty(choicesErrors)) {
498
+ errors.choicesErrors = choicesErrors;
499
+ }
500
+
501
+ if (!isEmpty(categoriesErrors)) {
502
+ errors.categoriesErrors = categoriesErrors;
503
+ }
504
+
505
+ return errors;
506
+ };
507
+
508
+ export { createCorrectResponseSession, createDefaultModel, getCorrectness, getPartialScore, getTotalScore, model, normalize, outcome, validate };
509
+ //# sourceMappingURL=controller.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"controller.js","sources":["../../../node_modules/@babel/runtime/helpers/esm/asyncToGenerator.js","../../../node_modules/@babel/runtime/helpers/esm/defineProperty.js","../controller/src/utils.js","../controller/src/defaults.js","../controller/src/index.js"],"sourcesContent":["function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {\n try {\n var info = gen[key](arg);\n var value = info.value;\n } catch (error) {\n reject(error);\n return;\n }\n\n if (info.done) {\n resolve(value);\n } else {\n Promise.resolve(value).then(_next, _throw);\n }\n}\n\nexport default function _asyncToGenerator(fn) {\n return function () {\n var self = this,\n args = arguments;\n return new Promise(function (resolve, reject) {\n var gen = fn.apply(self, args);\n\n function _next(value) {\n asyncGeneratorStep(gen, resolve, reject, _next, _throw, \"next\", value);\n }\n\n function _throw(err) {\n asyncGeneratorStep(gen, resolve, reject, _next, _throw, \"throw\", err);\n }\n\n _next(undefined);\n });\n };\n}","export default function _defineProperty(obj, key, value) {\n if (key in obj) {\n Object.defineProperty(obj, key, {\n value: value,\n enumerable: true,\n configurable: true,\n writable: true\n });\n } else {\n obj[key] = value;\n }\n\n return obj;\n}","// used in configure too, for consistency modify it there too\nexport const multiplePlacements = { enabled: 'Yes', disabled: 'No', perChoice: 'Set Per Choice' };\n\n// used to validate the config\nexport const isCorrectResponseDuplicated = (choices,alternate) => {\n if (choices.length < 1 || alternate.length < 1){\n return -1;\n }\n\n const stringChoices = JSON.stringify(choices.sort());\n const stringAlternate = alternate.reduce((total, current) => current.length > 0 ? [...total, JSON.stringify(current.sort())] : total, []);\n const foundIndexDuplicate = stringAlternate.findIndex(alternate => alternate.length && alternate === stringChoices);\n\n return foundIndexDuplicate;\n};\n\nexport const isAlternateDuplicated = (alternate) => {\n if (alternate.length <= 1){\n return -1;\n }\n\n const elementSet = new Set();\n const stringAlternate = alternate.reduce((total, current) => current.length > 0 ? [...total, JSON.stringify(current.sort())] : total, []);\n\n for (let i = 0; i < stringAlternate.length; i++) {\n if (elementSet.has(stringAlternate[i]) && stringAlternate[i]) {\n return i;\n }\n\n elementSet.add(stringAlternate[i]);\n }\n\n return -1;\n};\n","import { multiplePlacements } from './utils';\n\nexport default {\n allowMultiplePlacementsEnabled: multiplePlacements.enabled,\n alternates: [],\n categories: [],\n categoriesPerRow: 2,\n choices: [],\n choicesLabel: '',\n choicesPosition: 'below',\n correctResponse: [],\n feedbackEnabled: false,\n lockChoiceOrder: true,\n maxAnswerChoices: 6,\n maxChoicesPerCategory: 0,\n partialScoring: true,\n prompt: '',\n promptEnabled: true,\n rationale: '',\n rationaleEnabled: true,\n rowLabels: [''],\n studentInstructionsEnabled: true,\n teacherInstructions: '',\n teacherInstructionsEnabled: true,\n toolbarEditorPosition: 'bottom',\n minRowHeight: '80px',\n};\n","import isEmpty from 'lodash/isEmpty';\nimport { buildState, score } from '@pie-lib/categorize';\nimport { getFeedbackForCorrectness } from '@pie-lib/feedback';\nimport { lockChoices, getShuffledChoices, partialScoring } from '@pie-lib/controller-utils';\nimport Translator from '@pie-lib/translator';\n\nconst { translator } = Translator;\nimport defaults from './defaults';\nimport { isAlternateDuplicated, isCorrectResponseDuplicated } from './utils';\n\n// eslint-disable-next-line no-console\n\nexport { score };\n\nexport const getPartialScore = (correctResponse, builtCategories) => {\n // in the resulted best scenario we make a sum with all the correct responses\n // and all the placements\n const { placements, score } = builtCategories.reduce(\n (acc, { choices = [] }) => ({\n placements: acc.placements + choices.length,\n score: acc.score + choices.filter((ch) => ch.correct).length,\n }),\n { placements: 0, score: 0 },\n );\n\n // in the correct response, we make a sum of the max possible score\n const { maxScore } = correctResponse.reduce(\n (acc, { choices }) => ({\n maxScore: acc.maxScore + choices.length,\n }),\n { maxScore: 0 },\n );\n\n // if there are any extra placements, we subtract from the obtained score\n const extraPlacements = placements > maxScore ? placements - maxScore : 0;\n const totalScore = (score - extraPlacements) / maxScore;\n\n return totalScore < 0 ? 0 : parseFloat(totalScore.toFixed(2));\n};\n\nconst getAlternates = (correctResponse) =>\n correctResponse.map((c) => c.alternateResponses).filter((alternate) => alternate);\n\nexport const getTotalScore = (question, session, env) => {\n if (!session) {\n return 0;\n }\n\n if (Object.keys(session).length === 0) {\n return 0;\n }\n const { categories, choices } = question || {};\n let { correctResponse } = question || {};\n let { answers } = session || {};\n answers = answers || [];\n correctResponse = correctResponse || [];\n\n // this function is used in pie-ui/categorize as well, in order to get the best scenario\n // so we get the best scenario and calculate the score\n const { categories: builtCategories, correct } = buildState(categories, choices, answers, correctResponse);\n\n const alternates = getAlternates(correctResponse);\n const enabled = partialScoring.enabled(question, env);\n\n // if there are any alternates, there will be no partial scoring!\n if (enabled && !alternates.length) {\n // we apply partial scoring\n return getPartialScore(correctResponse, builtCategories);\n }\n\n // else we apply dichotomous\n return correct ? 1 : 0;\n};\n\nexport const getCorrectness = (question, session, env) => {\n return new Promise((resolve) => {\n if (env.mode === 'evaluate') {\n const score = getTotalScore(question, session, env);\n if (score === 1) {\n resolve('correct');\n } else if (score === 0) {\n resolve('incorrect');\n } else {\n resolve('partially-correct');\n }\n } else {\n resolve(undefined);\n }\n });\n};\n\nexport const createDefaultModel = (model = {}) =>\n new Promise((resolve) => {\n resolve({\n ...defaults,\n ...model,\n });\n });\n\nexport const normalize = (question) => ({ ...defaults, ...question });\n\n/**\n *\n * @param {*} question\n * @param {*} session\n * @param {*} env\n * @param {*} updateSession - optional - a function that will set the properties passed into it on the session.\n */\nexport const model = (question, session, env, updateSession) =>\n new Promise(async (resolve) => {\n const normalizedQuestion = normalize(question);\n const answerCorrectness = await getCorrectness(normalizedQuestion, session, env);\n\n const { mode, role } = env || {};\n\n const {\n categories,\n categoriesPerRow,\n choicesLabel,\n choicesPosition,\n correctResponse,\n feedback,\n feedbackEnabled,\n promptEnabled,\n prompt,\n rowLabels,\n rationaleEnabled,\n rationale,\n teacherInstructionsEnabled,\n teacherInstructions,\n language,\n maxChoicesPerCategory,\n extraCSSRules,\n minRowHeight,\n fontSizeFactor,\n autoplayAudioEnabled,\n completeAudioEnabled,\n customAudioButton,\n } = normalizedQuestion;\n let { choices, note } = normalizedQuestion;\n let fb;\n\n const lockChoiceOrder = lockChoices(normalizedQuestion, session, env);\n\n const filteredCorrectResponse = correctResponse.map((response) => {\n const filteredChoices = (response.choices || []).filter((choice) => choice !== 'null');\n return { ...response, choices: filteredChoices };\n });\n\n if (mode === 'evaluate' && feedbackEnabled) {\n fb = await getFeedbackForCorrectness(answerCorrectness, feedback);\n }\n\n if (!lockChoiceOrder) {\n choices = await getShuffledChoices(choices, session, updateSession, 'id');\n }\n\n if (!note) {\n note = translator.t('common:commonCorrectAnswerWithAlternates', { lng: language });\n }\n\n const alternates = getAlternates(filteredCorrectResponse);\n const out = {\n categories: categories || [],\n categoriesPerRow: categoriesPerRow || 2,\n maxChoicesPerCategory,\n correctness: answerCorrectness,\n choices: choices || [],\n choicesLabel: choicesLabel || '',\n choicesPosition,\n disabled: mode !== 'gather',\n feedback: fb,\n lockChoiceOrder,\n prompt: promptEnabled ? prompt : null,\n rowLabels,\n note,\n env,\n showNote: alternates && alternates.length > 0,\n correctResponse: mode === 'evaluate' ? filteredCorrectResponse : undefined,\n language,\n extraCSSRules,\n fontSizeFactor,\n minRowHeight: minRowHeight,\n autoplayAudioEnabled,\n completeAudioEnabled,\n customAudioButton,\n };\n\n if (role === 'instructor' && (mode === 'view' || mode === 'evaluate')) {\n out.rationale = rationaleEnabled ? rationale : null;\n out.teacherInstructions = teacherInstructionsEnabled ? teacherInstructions : null;\n } else {\n out.rationale = null;\n out.teacherInstructions = null;\n }\n\n resolve(out);\n });\n\nexport const outcome = (question, session, env) => {\n if (env.mode !== 'evaluate') {\n return Promise.reject(new Error('Can not call outcome when mode is not evaluate'));\n } else {\n return new Promise((resolve) => {\n resolve({\n score: getTotalScore(question, session, env),\n empty: !session || isEmpty(session),\n });\n });\n }\n};\n\nexport const createCorrectResponseSession = (question, env) => {\n return new Promise((resolve) => {\n const { mode, role } = env || {};\n\n if (mode !== 'evaluate' && role === 'instructor') {\n const { correctResponse } = question;\n\n resolve({ answers: correctResponse, id: 1 });\n } else {\n return resolve(null);\n }\n });\n};\n\n// remove all html tags\nconst getInnerText = (html) => (html || '').replaceAll(/<[^>]*>/g, '');\n\n// remove all html tags except img, iframe and source tag for audio\nconst getContent = (html) => (html || '').replace(/(<(?!img|iframe|source)([^>]+)>)/gi, '');\n\nexport const validate = (model = {}, config = {}) => {\n const { categories, choices, correctResponse, maxAnswerChoices } = model;\n const {\n minChoices = 1,\n minCategories = 1,\n maxCategories = 12,\n maxLengthPerChoice = 300,\n maxLengthPerCategory = 150,\n } = config;\n const reversedChoices = [...(choices || [])].reverse();\n const errors = {};\n const choicesErrors = {};\n const categoriesErrors = {};\n\n ['teacherInstructions', 'prompt', 'rationale'].forEach((field) => {\n if (config[field]?.required && !getContent(model[field])) {\n errors[field] = 'This field is required.';\n }\n });\n\n (categories || []).forEach((category) => {\n const { id, label } = category;\n\n if (getInnerText(label).length > maxLengthPerCategory) {\n categoriesErrors[id] = `Category labels should be no more than ${maxLengthPerCategory} characters long.`;\n }\n });\n\n (reversedChoices || []).forEach((choice, index) => {\n const { id, content } = choice;\n\n if (getInnerText(content).length > maxLengthPerChoice) {\n choicesErrors[id] = `Tokens should be no more than ${maxLengthPerChoice} characters long.`;\n }\n\n if (!getContent(content)) {\n choicesErrors[id] = 'Tokens should not be empty.';\n } else {\n const identicalAnswer = reversedChoices.slice(index + 1).some((c) => c.content === content);\n\n if (identicalAnswer) {\n choicesErrors[id] = 'Tokens content should be unique.';\n }\n }\n });\n\n const nbOfCategories = (categories || []).length;\n const nbOfChoices = (choices || []).length;\n\n if (nbOfCategories > maxCategories) {\n errors.categoriesError = `No more than ${maxCategories} categories should be defined.`;\n } else if (nbOfCategories < minCategories) {\n errors.categoriesError = `There should be at least ${minCategories} category defined.`;\n }\n\n if (nbOfChoices < minChoices) {\n errors.choicesError = `There should be at least ${minChoices} choices defined.`;\n } else if (nbOfChoices > maxAnswerChoices) {\n errors.choicesError = `No more than ${maxAnswerChoices} choices should be defined.`;\n }\n\n if (nbOfChoices && nbOfCategories) {\n let hasAssociations = false;\n\n (correctResponse || []).forEach((response) => {\n const { choices = [], alternateResponses = [] } = response;\n\n if (choices.length) {\n hasAssociations = true;\n } else {\n alternateResponses.forEach((alternate) => {\n if ((alternate || []).length) {\n hasAssociations = true;\n }\n });\n }\n });\n\n let duplicateAlternateIndex = -1;\n let duplicateCategory = '';\n (correctResponse || []).forEach((response) => {\n const { choices = [], alternateResponses = [], category } = response;\n\n if (duplicateAlternateIndex === -1) {\n duplicateAlternateIndex = isCorrectResponseDuplicated(choices, alternateResponses);\n\n if (duplicateAlternateIndex === -1) {\n duplicateAlternateIndex = isAlternateDuplicated(alternateResponses);\n }\n\n duplicateCategory = category;\n }\n });\n\n if (duplicateAlternateIndex > -1) {\n errors.duplicateAlternate = { index: duplicateAlternateIndex, category: duplicateCategory };\n }\n\n if (!hasAssociations) {\n errors.associationError = 'At least one token should be assigned to at least one category.';\n }\n }\n\n if (!isEmpty(choicesErrors)) {\n errors.choicesErrors = choicesErrors;\n }\n\n if (!isEmpty(categoriesErrors)) {\n errors.categoriesErrors = categoriesErrors;\n }\n\n return errors;\n};\n"],"names":["multiplePlacements","enabled","disabled","perChoice","isCorrectResponseDuplicated","choices","alternate","length","stringChoices","JSON","stringify","sort","stringAlternate","reduce","total","current","foundIndexDuplicate","findIndex","isAlternateDuplicated","elementSet","Set","i","has","add","allowMultiplePlacementsEnabled","alternates","categories","categoriesPerRow","choicesLabel","choicesPosition","correctResponse","feedbackEnabled","lockChoiceOrder","maxAnswerChoices","maxChoicesPerCategory","partialScoring","prompt","promptEnabled","rationale","rationaleEnabled","rowLabels","studentInstructionsEnabled","teacherInstructions","teacherInstructionsEnabled","toolbarEditorPosition","minRowHeight","translator","Translator","getPartialScore","builtCategories","placements","score","acc","filter","ch","correct","maxScore","extraPlacements","totalScore","parseFloat","toFixed","getAlternates","map","c","alternateResponses","getTotalScore","question","session","env","Object","keys","answers","buildState","getCorrectness","Promise","resolve","mode","undefined","createDefaultModel","model","defaults","normalize","updateSession","normalizedQuestion","answerCorrectness","role","feedback","language","extraCSSRules","fontSizeFactor","autoplayAudioEnabled","completeAudioEnabled","customAudioButton","note","fb","lockChoices","filteredCorrectResponse","response","filteredChoices","choice","getFeedbackForCorrectness","getShuffledChoices","t","lng","out","correctness","showNote","outcome","reject","Error","empty","isEmpty","createCorrectResponseSession","id","getInnerText","html","replaceAll","getContent","replace","validate","config","minChoices","minCategories","maxCategories","maxLengthPerChoice","maxLengthPerCategory","reversedChoices","reverse","errors","choicesErrors","categoriesErrors","forEach","field","required","category","label","index","content","identicalAnswer","slice","some","nbOfCategories","nbOfChoices","categoriesError","choicesError","hasAssociations","duplicateAlternateIndex","duplicateCategory","duplicateAlternate","associationError"],"mappings":"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"}