@pie-element/match 10.0.1 → 11.0.3-esm.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/esm/controller.js CHANGED
@@ -2,9 +2,27 @@ import isEqual from 'lodash/isEqual';
2
2
  import isEmpty from 'lodash/isEmpty';
3
3
  import cloneDeep from 'lodash/cloneDeep';
4
4
  import { getFeedbackForCorrectness } from '@pie-lib/feedback';
5
- import { partialScoring, lockChoices, getShuffledChoices } from '@pie-lib/controller-utils';
5
+ import { lockChoices, getShuffledChoices, partialScoring } from '@pie-lib/controller-utils';
6
6
  import debug from 'debug';
7
7
 
8
+ function _extends() {
9
+ _extends = Object.assign || function (target) {
10
+ for (var i = 1; i < arguments.length; i++) {
11
+ var source = arguments[i];
12
+
13
+ for (var key in source) {
14
+ if (Object.prototype.hasOwnProperty.call(source, key)) {
15
+ target[key] = source[key];
16
+ }
17
+ }
18
+ }
19
+
20
+ return target;
21
+ };
22
+
23
+ return _extends.apply(this, arguments);
24
+ }
25
+
8
26
  function _objectWithoutPropertiesLoose(source, excluded) {
9
27
  if (source == null) return {};
10
28
  var target = {};
@@ -20,76 +38,6 @@ function _objectWithoutPropertiesLoose(source, excluded) {
20
38
  return target;
21
39
  }
22
40
 
23
- function _objectWithoutProperties(source, excluded) {
24
- if (source == null) return {};
25
- var target = _objectWithoutPropertiesLoose(source, excluded);
26
- var key, i;
27
-
28
- if (Object.getOwnPropertySymbols) {
29
- var sourceSymbolKeys = Object.getOwnPropertySymbols(source);
30
-
31
- for (i = 0; i < sourceSymbolKeys.length; i++) {
32
- key = sourceSymbolKeys[i];
33
- if (excluded.indexOf(key) >= 0) continue;
34
- if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;
35
- target[key] = source[key];
36
- }
37
- }
38
-
39
- return target;
40
- }
41
-
42
- function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
43
- try {
44
- var info = gen[key](arg);
45
- var value = info.value;
46
- } catch (error) {
47
- reject(error);
48
- return;
49
- }
50
-
51
- if (info.done) {
52
- resolve(value);
53
- } else {
54
- Promise.resolve(value).then(_next, _throw);
55
- }
56
- }
57
-
58
- function _asyncToGenerator(fn) {
59
- return function () {
60
- var self = this,
61
- args = arguments;
62
- return new Promise(function (resolve, reject) {
63
- var gen = fn.apply(self, args);
64
-
65
- function _next(value) {
66
- asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
67
- }
68
-
69
- function _throw(err) {
70
- asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
71
- }
72
-
73
- _next(undefined);
74
- });
75
- };
76
- }
77
-
78
- function _defineProperty(obj, key, value) {
79
- if (key in obj) {
80
- Object.defineProperty(obj, key, {
81
- value: value,
82
- enumerable: true,
83
- configurable: true,
84
- writable: true
85
- });
86
- } else {
87
- obj[key] = value;
88
- }
89
-
90
- return obj;
91
- }
92
-
93
41
  var defaults = {
94
42
  choiceMode: 'radio',
95
43
  feedbackEnabled: false,
@@ -109,29 +57,24 @@ var defaults = {
109
57
  toolbarEditorPosition: 'bottom'
110
58
  };
111
59
 
112
- var _excluded = ["extraCSSRules", "feedbackEnabled", "promptEnabled", "prompt", "lockChoiceOrder"];
60
+ const _excluded = ["extraCSSRules", "feedbackEnabled", "promptEnabled", "prompt", "lockChoiceOrder"];
61
+ const log = debug('@pie-element:match:controller');
113
62
 
114
- 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; }
115
-
116
- 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; }
117
- var log = debug('@pie-element:match:controller');
118
-
119
- var getResponseCorrectness = function getResponseCorrectness(model, answers) {
120
- var env = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
121
- var isPartialScoring = partialScoring.enabled(model, env);
122
- var rows = model.rows;
123
- var checkboxMode = model.choiceMode === 'checkbox';
63
+ const getResponseCorrectness = (model, answers, env = {}) => {
64
+ const isPartialScoring = partialScoring.enabled(model, env);
65
+ const rows = model.rows;
66
+ const checkboxMode = model.choiceMode === 'checkbox';
124
67
 
125
68
  if (!answers || Object.keys(answers).length === 0) {
126
69
  return 'unanswered';
127
70
  }
128
71
 
129
- var totalCorrectAnswers = checkboxMode ? getTotalCorrectAnswers(model) : getTotalCorrect(model);
130
- var correctAnswers;
131
- var incorrectAnswers = 0;
72
+ const totalCorrectAnswers = checkboxMode ? getTotalCorrectAnswers(model) : getTotalCorrect(model);
73
+ let correctAnswers;
74
+ let incorrectAnswers = 0;
132
75
 
133
76
  if (checkboxMode) {
134
- var checkboxes = getCheckboxes(rows, answers);
77
+ const checkboxes = getCheckboxes(rows, answers);
135
78
  correctAnswers = checkboxes.correctAnswers;
136
79
  incorrectAnswers = checkboxes.incorrectAnswers;
137
80
  } else {
@@ -149,19 +92,17 @@ var getResponseCorrectness = function getResponseCorrectness(model, answers) {
149
92
  return 'incorrect';
150
93
  };
151
94
 
152
- var getCorrectness = function getCorrectness(question, env) {
153
- var answers = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
154
-
95
+ const getCorrectness = (question, env, answers = {}) => {
155
96
  if (env.mode === 'evaluate') {
156
97
  return getResponseCorrectness(question, answers, env);
157
98
  }
158
99
  };
159
100
 
160
- var getCheckboxes = (rows, answers) => {
161
- var correctAnswers = 0;
162
- var incorrectAnswers = 0;
101
+ const getCheckboxes = (rows, answers) => {
102
+ let correctAnswers = 0;
103
+ let incorrectAnswers = 0;
163
104
  rows.forEach(row => {
164
- var answer = answers[row.id];
105
+ const answer = answers[row.id];
165
106
 
166
107
  if (answer) {
167
108
  row.values.forEach((v, i) => {
@@ -179,8 +120,8 @@ var getCheckboxes = (rows, answers) => {
179
120
  };
180
121
  };
181
122
 
182
- var getCorrectRadios = (rows, answers) => {
183
- var correctAnswers = 0;
123
+ const getCorrectRadios = (rows, answers) => {
124
+ let correctAnswers = 0;
184
125
  rows.forEach(row => {
185
126
  if (isEqual(row.values, answers[row.id])) {
186
127
  correctAnswers += 1;
@@ -189,14 +130,14 @@ var getCorrectRadios = (rows, answers) => {
189
130
  return correctAnswers;
190
131
  };
191
132
 
192
- var getTotalCorrect = question => {
193
- var checkboxMode = question.choiceMode === 'checkbox';
194
- var matchingTable = checkboxMode ? question.layout - 1 : 1;
133
+ const getTotalCorrect = question => {
134
+ const checkboxMode = question.choiceMode === 'checkbox';
135
+ const matchingTable = checkboxMode ? question.layout - 1 : 1;
195
136
  return (question.rows.length || 0) * matchingTable;
196
137
  };
197
138
 
198
- var getTotalCorrectAnswers = question => {
199
- var noOfTotalCorrectAnswers = 0;
139
+ const getTotalCorrectAnswers = question => {
140
+ let noOfTotalCorrectAnswers = 0;
200
141
  question.rows.forEach(row => {
201
142
  row.values.forEach(value => {
202
143
  if (value) {
@@ -207,41 +148,38 @@ var getTotalCorrectAnswers = question => {
207
148
  return noOfTotalCorrectAnswers;
208
149
  };
209
150
 
210
- var getPartialScore = (question, answers) => {
211
- var checkboxMode = question.choiceMode === 'checkbox';
151
+ const getPartialScore = (question, answers) => {
152
+ const checkboxMode = question.choiceMode === 'checkbox';
212
153
 
213
154
  if (checkboxMode) {
214
- var {
155
+ const {
215
156
  correctAnswers,
216
157
  incorrectAnswers
217
158
  } = getCheckboxes(question.rows, answers);
218
- var totalCorrect = getTotalCorrectAnswers(question);
219
- var total = totalCorrect === 0 ? 1 : totalCorrect;
159
+ const totalCorrect = getTotalCorrectAnswers(question);
160
+ const total = totalCorrect === 0 ? 1 : totalCorrect;
220
161
 
221
162
  if (correctAnswers + incorrectAnswers > totalCorrect) {
222
- var extraAnswers = correctAnswers + incorrectAnswers - totalCorrect;
223
- var score = parseFloat(((correctAnswers - extraAnswers) / total).toFixed(2));
163
+ const extraAnswers = correctAnswers + incorrectAnswers - totalCorrect;
164
+ const score = parseFloat(((correctAnswers - extraAnswers) / total).toFixed(2));
224
165
  return score < 0 ? 0 : score;
225
166
  } else {
226
167
  return parseFloat((correctAnswers / total).toFixed(2));
227
168
  }
228
169
  } else {
229
- var _correctAnswers = getCorrectRadios(question.rows, answers);
230
-
231
- var _totalCorrect = getTotalCorrect(question) === 0 ? 1 : getTotalCorrect(question);
232
-
233
- return parseFloat((_correctAnswers / _totalCorrect).toFixed(2));
170
+ const correctAnswers = getCorrectRadios(question.rows, answers);
171
+ const totalCorrect = getTotalCorrect(question) === 0 ? 1 : getTotalCorrect(question);
172
+ return parseFloat((correctAnswers / totalCorrect).toFixed(2));
234
173
  }
235
174
  };
236
175
 
237
- var getOutComeScore = function getOutComeScore(question, env) {
238
- var answers = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
239
- var correctness = getCorrectness(question, env, answers);
240
- var isPartialScoring = partialScoring.enabled(question, env);
176
+ const getOutComeScore = (question, env, answers = {}) => {
177
+ const correctness = getCorrectness(question, env, answers);
178
+ const isPartialScoring = partialScoring.enabled(question, env);
241
179
  return correctness === 'correct' ? 1 : correctness === 'partial' && isPartialScoring ? getPartialScore(question, answers) : 0;
242
180
  };
243
181
 
244
- var outcome = (question, session, env) => {
182
+ const outcome = (question, session, env) => {
245
183
  return new Promise(resolve => {
246
184
  if (env.mode !== 'evaluate') {
247
185
  resolve({
@@ -256,20 +194,19 @@ var outcome = (question, session, env) => {
256
194
  });
257
195
  }
258
196
 
259
- var out = {
197
+ const out = {
260
198
  score: getOutComeScore(question, env, session.answers)
261
199
  };
262
200
  resolve(out);
263
201
  }
264
202
  });
265
203
  };
266
- function createDefaultModel() {
267
- var model = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
204
+ function createDefaultModel(model = {}) {
268
205
  return new Promise(resolve => {
269
- resolve(_objectSpread(_objectSpread({}, defaults), model));
206
+ resolve(_extends({}, defaults, model));
270
207
  });
271
208
  }
272
- var normalize = question => _objectSpread(_objectSpread({}, defaults), question);
209
+ const normalize = question => _extends({}, defaults, question);
273
210
  /**
274
211
  *
275
212
  * @param {*} question
@@ -279,90 +216,84 @@ var normalize = question => _objectSpread(_objectSpread({}, defaults), question)
279
216
  */
280
217
 
281
218
  function model(question, session, env, updateSession) {
282
- return new Promise( /*#__PURE__*/function () {
283
- var _ref = _asyncToGenerator(function* (resolve) {
284
- var normalizedQuestion = cloneDeep(normalize(question));
285
- var correctness, score;
286
-
287
- if ((!session || isEmpty(session)) && env.mode === 'evaluate') {
288
- correctness = 'unanswered';
289
- score = '0%';
290
- } else {
291
- correctness = getCorrectness(normalizedQuestion, env, session && session.answers);
292
- score = "".concat(getOutComeScore(normalizedQuestion, env, session && session.answers) * 100, "%");
293
- }
219
+ return new Promise(async resolve => {
220
+ const normalizedQuestion = cloneDeep(normalize(question));
221
+ let correctness, score;
294
222
 
295
- var correctResponse = {};
296
- var correctInfo = {
297
- score,
298
- correctness
299
- };
300
- var lockChoiceOrder = lockChoices(normalizedQuestion, session, env);
223
+ if ((!session || isEmpty(session)) && env.mode === 'evaluate') {
224
+ correctness = 'unanswered';
225
+ score = '0%';
226
+ } else {
227
+ correctness = getCorrectness(normalizedQuestion, env, session && session.answers);
228
+ score = `${getOutComeScore(normalizedQuestion, env, session && session.answers) * 100}%`;
229
+ }
301
230
 
302
- if (!lockChoiceOrder) {
303
- normalizedQuestion.rows = yield getShuffledChoices(normalizedQuestion.rows, session, updateSession, 'id');
304
- }
231
+ const correctResponse = {};
232
+ const correctInfo = {
233
+ score,
234
+ correctness
235
+ };
236
+ const lockChoiceOrder = lockChoices(normalizedQuestion, session, env);
305
237
 
306
- normalizedQuestion.rows.forEach(row => {
307
- correctResponse[row.id] = row.values;
238
+ if (!lockChoiceOrder) {
239
+ normalizedQuestion.rows = await getShuffledChoices(normalizedQuestion.rows, session, updateSession, 'id');
240
+ }
308
241
 
309
- if (env.mode !== 'evaluate') {
310
- delete row.values;
311
- }
242
+ normalizedQuestion.rows.forEach(row => {
243
+ correctResponse[row.id] = row.values;
244
+
245
+ if (env.mode !== 'evaluate') {
246
+ delete row.values;
247
+ }
248
+ });
249
+ const fb = env.mode === 'evaluate' && normalizedQuestion.feedbackEnabled ? getFeedbackForCorrectness(correctInfo.correctness, normalizedQuestion.feedback) : Promise.resolve(undefined);
250
+ fb.then(feedback => {
251
+ const {
252
+ extraCSSRules,
253
+ feedbackEnabled,
254
+ promptEnabled,
255
+ prompt,
256
+ lockChoiceOrder
257
+ } = normalizedQuestion,
258
+ essentials = _objectWithoutPropertiesLoose(normalizedQuestion, _excluded);
259
+
260
+ const out = _extends({}, essentials, {
261
+ extraCSSRules,
262
+ allowFeedback: feedbackEnabled,
263
+ prompt: promptEnabled ? prompt : null,
264
+ shuffled: !lockChoiceOrder,
265
+ feedback,
266
+ disabled: env.mode !== 'gather',
267
+ view: env.mode === 'view'
312
268
  });
313
- var fb = env.mode === 'evaluate' && normalizedQuestion.feedbackEnabled ? getFeedbackForCorrectness(correctInfo.correctness, normalizedQuestion.feedback) : Promise.resolve(undefined);
314
- fb.then(feedback => {
315
- var {
316
- extraCSSRules,
317
- feedbackEnabled,
318
- promptEnabled,
319
- prompt,
320
- lockChoiceOrder
321
- } = normalizedQuestion,
322
- essentials = _objectWithoutProperties(normalizedQuestion, _excluded);
323
-
324
- var out = _objectSpread(_objectSpread({}, essentials), {}, {
325
- extraCSSRules,
326
- allowFeedback: feedbackEnabled,
327
- prompt: promptEnabled ? prompt : null,
328
- shuffled: !lockChoiceOrder,
329
- feedback,
330
- disabled: env.mode !== 'gather',
331
- view: env.mode === 'view'
332
- });
333
269
 
334
- if (env.role === 'instructor' && (env.mode === 'view' || env.mode === 'evaluate')) {
335
- out.teacherInstructions = normalizedQuestion.teacherInstructionsEnabled ? normalizedQuestion.teacherInstructions : null;
336
- out.rationale = normalizedQuestion.rationaleEnabled ? normalizedQuestion.rationale : null;
337
- } else {
338
- out.rationale = null;
339
- out.teacherInstructions = null;
340
- }
270
+ if (env.role === 'instructor' && (env.mode === 'view' || env.mode === 'evaluate')) {
271
+ out.teacherInstructions = normalizedQuestion.teacherInstructionsEnabled ? normalizedQuestion.teacherInstructions : null;
272
+ out.rationale = normalizedQuestion.rationaleEnabled ? normalizedQuestion.rationale : null;
273
+ } else {
274
+ out.rationale = null;
275
+ out.teacherInstructions = null;
276
+ }
341
277
 
342
- if (env.mode === 'evaluate') {
343
- Object.assign(out, {
344
- correctResponse,
345
- correctness: correctInfo
346
- });
347
- }
278
+ if (env.mode === 'evaluate') {
279
+ Object.assign(out, {
280
+ correctResponse,
281
+ correctness: correctInfo
282
+ });
283
+ }
348
284
 
349
- log('out: ', out);
350
- resolve(out);
351
- });
285
+ log('out: ', out);
286
+ resolve(out);
352
287
  });
353
-
354
- return function (_x) {
355
- return _ref.apply(this, arguments);
356
- };
357
- }());
288
+ });
358
289
  }
359
- var createCorrectResponseSession = (question, env) => {
290
+ const createCorrectResponseSession = (question, env) => {
360
291
  return new Promise(resolve => {
361
292
  if (env.mode !== 'evaluate' && env.role === 'instructor') {
362
- var {
293
+ const {
363
294
  rows
364
295
  } = question;
365
- var answers = {};
296
+ const answers = {};
366
297
  rows.forEach(r => {
367
298
  answers[r.id] = r.values;
368
299
  });
@@ -376,20 +307,18 @@ var createCorrectResponseSession = (question, env) => {
376
307
  });
377
308
  }; // remove all html tags
378
309
 
379
- var getInnerText = html => (html || '').replaceAll(/<[^>]*>/g, ''); // remove all html tags except img, iframe and source tag for audio
310
+ const getInnerText = html => (html || '').replaceAll(/<[^>]*>/g, ''); // remove all html tags except img, iframe and source tag for audio
380
311
 
381
312
 
382
- var getContent = html => (html || '').replace(/(<(?!img|iframe|source)([^>]+)>)/gi, '');
313
+ const getContent = html => (html || '').replace(/(<(?!img|iframe|source)([^>]+)>)/gi, '');
383
314
 
384
- var validate = function validate() {
385
- var model = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
386
- var config = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
387
- var {
315
+ const validate = (model = {}, config = {}) => {
316
+ const {
388
317
  rows,
389
318
  choiceMode,
390
319
  headers
391
320
  } = model;
392
- var {
321
+ const {
393
322
  minQuestions,
394
323
  maxQuestions,
395
324
  maxLengthQuestionsHeading,
@@ -397,25 +326,25 @@ var validate = function validate() {
397
326
  maxLengthAnswers,
398
327
  maxLengthFirstColumnHeading
399
328
  } = config;
400
- var rowsErrors = {};
401
- var columnsErrors = {};
402
- var errors = {};
329
+ const rowsErrors = {};
330
+ const columnsErrors = {};
331
+ const errors = {};
403
332
  ['teacherInstructions', 'prompt', 'rationale'].forEach(field => {
404
333
  var _config$field;
405
334
 
406
- if ((_config$field = config[field]) !== null && _config$field !== void 0 && _config$field.required && !getContent(model[field])) {
335
+ if ((_config$field = config[field]) != null && _config$field.required && !getContent(model[field])) {
407
336
  errors[field] = 'This field is required.';
408
337
  }
409
338
  });
410
339
 
411
340
  if (rows.length < minQuestions) {
412
- errors.noOfRowsError = "There should be at least ".concat(minQuestions, " question rows.");
341
+ errors.noOfRowsError = `There should be at least ${minQuestions} question rows.`;
413
342
  } else if (rows.length > maxQuestions) {
414
- errors.noOfRowsError = "No more than ".concat(maxQuestions, " question rows should be defined.");
343
+ errors.noOfRowsError = `No more than ${maxQuestions} question rows should be defined.`;
415
344
  }
416
345
 
417
346
  (rows || []).forEach((row, index) => {
418
- var {
347
+ const {
419
348
  id,
420
349
  values = [],
421
350
  title
@@ -423,21 +352,21 @@ var validate = function validate() {
423
352
  rowsErrors[id] = '';
424
353
 
425
354
  if (maxLengthQuestionsHeading && getInnerText(title).length > maxLengthQuestionsHeading) {
426
- rowsErrors[id] += "Content length should be maximum ".concat(maxLengthQuestionsHeading, " characters. ");
355
+ rowsErrors[id] += `Content length should be maximum ${maxLengthQuestionsHeading} characters. `;
427
356
  }
428
357
 
429
358
  if (!getContent(title)) {
430
359
  rowsErrors[id] += 'Content should not be empty. ';
431
360
  } else {
432
361
  // check for identical content with the previous answers
433
- var identicalAnswer = rows.slice(0, index).some(r => getContent(r.title) === getContent(title));
362
+ const identicalAnswer = rows.slice(0, index).some(r => getContent(r.title) === getContent(title));
434
363
 
435
364
  if (identicalAnswer) {
436
365
  rowsErrors[id] += 'Content should be unique. ';
437
366
  }
438
367
  }
439
368
 
440
- var hasCorrectResponse = values.some(value => !!value);
369
+ const hasCorrectResponse = values.some(value => !!value);
441
370
 
442
371
  if (!hasCorrectResponse) {
443
372
  rowsErrors[id] += 'No correct response defined.';
@@ -445,48 +374,48 @@ var validate = function validate() {
445
374
  });
446
375
 
447
376
  if (maxAnswers && headers.length - 1 > maxAnswers) {
448
- errors.columnsLengthError = "There should be maximum ".concat(maxAnswers, " answers.");
377
+ errors.columnsLengthError = `There should be maximum ${maxAnswers} answers.`;
449
378
  }
450
379
 
451
380
  if (maxLengthFirstColumnHeading && headers[0].length > maxLengthFirstColumnHeading) {
452
- columnsErrors[0] = "Content length should be maximum ".concat(maxLengthFirstColumnHeading, " characters.");
381
+ columnsErrors[0] = `Content length should be maximum ${maxLengthFirstColumnHeading} characters.`;
453
382
  }
454
383
 
455
- var headersContent = (headers || []).map(heading => getContent(heading));
384
+ const headersContent = (headers || []).map(heading => getContent(heading));
456
385
  headersContent.shift(); // remove first column since it does not require validation
457
386
 
458
387
  headersContent.forEach((heading, index) => {
459
- var headerIndex = index + 1; // we need to add 1 because we removed first header from validation
388
+ const headerIndex = index + 1; // we need to add 1 because we removed first header from validation
460
389
 
461
390
  columnsErrors[headerIndex] = '';
462
391
 
463
392
  if (maxLengthAnswers && getInnerText(heading).length > maxLengthAnswers) {
464
- columnsErrors[headerIndex] += "Content length should be maximum ".concat(maxLengthAnswers, " characters. ");
393
+ columnsErrors[headerIndex] += `Content length should be maximum ${maxLengthAnswers} characters. `;
465
394
  }
466
395
 
467
396
  if (!heading) {
468
397
  columnsErrors[headerIndex] += 'Content should not be empty.';
469
398
  } else {
470
399
  // check for identical content with the previous headers
471
- var identicalAnswer = headersContent.slice(0, index).some(head => head === heading);
400
+ const identicalAnswer = headersContent.slice(0, index).some(head => head === heading);
472
401
 
473
402
  if (identicalAnswer) {
474
403
  columnsErrors[index + 1] += 'Content should be unique.';
475
404
  }
476
405
  }
477
406
  });
478
- var hasRowErrors = Object.values(rowsErrors).some(error => (error || '').length);
407
+ const hasRowErrors = Object.values(rowsErrors).some(error => (error || '').length);
479
408
 
480
409
  if (hasRowErrors) {
481
410
  errors.rowsErrors = rowsErrors;
482
- var noCorrectAnswer = Object.values(rowsErrors).some(error => (error || '').includes('No correct response defined.'));
411
+ const noCorrectAnswer = Object.values(rowsErrors).some(error => (error || '').includes('No correct response defined.'));
483
412
 
484
413
  if (noCorrectAnswer) {
485
414
  errors.correctResponseError = choiceMode === 'radio' ? 'There should be a correct response defined for every row.' : 'There should be at least one correct response defined for every row.';
486
415
  }
487
416
  }
488
417
 
489
- var hasColumnErrors = Object.values(columnsErrors).some(error => (error || '').length);
418
+ const hasColumnErrors = Object.values(columnsErrors).some(error => (error || '').length);
490
419
 
491
420
  if (hasColumnErrors) {
492
421
  errors.columnsErrors = columnsErrors;