@pie-element/explicit-constructed-response 9.3.4-next.3 → 10.0.0-beta.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.
Files changed (50) hide show
  1. package/CHANGELOG.md +0 -11
  2. package/configure/CHANGELOG.md +0 -11
  3. package/configure/lib/alternateResponses.js +139 -184
  4. package/configure/lib/alternateResponses.js.map +1 -1
  5. package/configure/lib/alternateSection.js +279 -370
  6. package/configure/lib/alternateSection.js.map +1 -1
  7. package/configure/lib/defaults.js +2 -3
  8. package/configure/lib/defaults.js.map +1 -1
  9. package/configure/lib/ecr-toolbar.js +127 -191
  10. package/configure/lib/ecr-toolbar.js.map +1 -1
  11. package/configure/lib/index.js +126 -203
  12. package/configure/lib/index.js.map +1 -1
  13. package/configure/lib/main.js +436 -552
  14. package/configure/lib/main.js.map +1 -1
  15. package/configure/lib/markupUtils.js +26 -49
  16. package/configure/lib/markupUtils.js.map +1 -1
  17. package/configure/lib/utils.js +5 -5
  18. package/configure/lib/utils.js.map +1 -1
  19. package/configure/package.json +9 -7
  20. package/controller/CHANGELOG.md +0 -11
  21. package/controller/lib/defaults.js +2 -3
  22. package/controller/lib/defaults.js.map +1 -1
  23. package/controller/lib/index.js +172 -260
  24. package/controller/lib/index.js.map +1 -1
  25. package/controller/package.json +3 -3
  26. package/lib/index.js +71 -115
  27. package/lib/index.js.map +1 -1
  28. package/lib/main.js +174 -248
  29. package/lib/main.js.map +1 -1
  30. package/lib/print.js +39 -83
  31. package/lib/print.js.map +1 -1
  32. package/package.json +14 -19
  33. package/esm/configure.js +0 -33096
  34. package/esm/configure.js.map +0 -1
  35. package/esm/controller.js +0 -5144
  36. package/esm/controller.js.map +0 -1
  37. package/esm/element.js +0 -11518
  38. package/esm/element.js.map +0 -1
  39. package/esm/package.json +0 -3
  40. package/esm/print.js +0 -12202
  41. package/esm/print.js.map +0 -1
  42. package/module/configure.js +0 -1
  43. package/module/controller.js +0 -7460
  44. package/module/demo.js +0 -45
  45. package/module/element.js +0 -1
  46. package/module/index.html +0 -21
  47. package/module/manifest.json +0 -22
  48. package/module/print-demo.js +0 -83
  49. package/module/print.html +0 -18
  50. package/module/print.js +0 -1
@@ -1,7 +1,6 @@
1
1
  "use strict";
2
2
 
3
3
  var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
-
5
4
  Object.defineProperty(exports, "__esModule", {
6
5
  value: true
7
6
  });
@@ -10,248 +9,184 @@ exports.model = model;
10
9
  exports.normalize = void 0;
11
10
  exports.outcome = outcome;
12
11
  exports.validate = exports.prepareVal = exports.prepareChoice = void 0;
13
-
14
- var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
15
-
16
- var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
17
-
18
- var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
19
-
20
- var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
21
-
22
- var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
23
-
24
12
  var _debug = _interopRequireDefault(require("debug"));
25
-
26
13
  var _map = _interopRequireDefault(require("lodash/map"));
27
-
28
14
  var _reduce = _interopRequireDefault(require("lodash/reduce"));
29
-
30
15
  var _find = _interopRequireDefault(require("lodash/find"));
31
-
32
16
  var _isEmpty = _interopRequireDefault(require("lodash/isEmpty"));
33
-
34
17
  var _he = require("he");
35
-
36
18
  var _controllerUtils = require("@pie-lib/controller-utils");
37
-
38
19
  var _translator = _interopRequireDefault(require("@pie-lib/translator"));
39
-
40
20
  var _defaults = _interopRequireDefault(require("./defaults"));
41
-
42
- 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; }
43
-
44
- 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) { (0, _defineProperty2["default"])(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; }
45
-
46
- var translator = _translator["default"].translator;
47
- var log = (0, _debug["default"])('explicit-constructed-response:controller');
48
-
49
- var prepareChoice = function prepareChoice(mode, defaultFeedback) {
50
- return function (choice) {
51
- var out = {
52
- label: choice.label,
53
- value: choice.value
54
- };
55
-
56
- if (mode === 'evaluate') {
57
- out.correct = true;
58
- var feedbackType = choice.feedback && choice.feedback.type || 'none';
59
-
60
- if (feedbackType === 'default') {
61
- out.feedback = defaultFeedback['correct'];
62
- } else if (feedbackType === 'custom') {
63
- out.feedback = choice.feedback.value;
64
- }
65
- }
66
-
67
- return out;
21
+ const {
22
+ translator
23
+ } = _translator.default;
24
+ const log = (0, _debug.default)('explicit-constructed-response:controller');
25
+ const prepareChoice = (mode, defaultFeedback) => choice => {
26
+ const out = {
27
+ label: choice.label,
28
+ value: choice.value
68
29
  };
30
+ if (mode === 'evaluate') {
31
+ out.correct = true;
32
+ const feedbackType = choice.feedback && choice.feedback.type || 'none';
33
+ if (feedbackType === 'default') {
34
+ out.feedback = defaultFeedback['correct'];
35
+ } else if (feedbackType === 'custom') {
36
+ out.feedback = choice.feedback.value;
37
+ }
38
+ }
39
+ return out;
69
40
  };
70
-
71
41
  exports.prepareChoice = prepareChoice;
72
-
73
- var getFeedback = function getFeedback(value) {
42
+ const getFeedback = value => {
74
43
  if (value) {
75
44
  return 'correct';
76
45
  }
77
-
78
46
  return 'incorrect';
79
- }; // also used in configure/src/markupUtils.js
80
-
47
+ };
81
48
 
82
- var getAdjustedLength = function getAdjustedLength(length) {
49
+ // also used in configure/src/markupUtils.js
50
+ const getAdjustedLength = length => {
51
+ if (Math.abs(length) === Infinity) {
52
+ return 2;
53
+ }
83
54
  if (length <= 2) {
84
55
  return length + 2;
85
56
  }
86
-
87
57
  if (length <= 4) {
88
58
  return length + 3;
89
59
  }
90
-
91
60
  if (length <= 6) {
92
61
  return length + 4;
93
62
  }
94
-
95
63
  return length + 5;
96
- }; // we can't use the dom parser here because it is not available in the node environment
97
-
64
+ };
98
65
 
99
- var decodeHtmlEntities = function decodeHtmlEntities(str) {
66
+ // we can't use the dom parser here because it is not available in the node environment
67
+ const decodeHtmlEntities = str => {
100
68
  if (!str) return '';
101
69
  return str.replace(/&lt;/g, '<').replace(/&gt;/g, '>').replace(/&quot;/g, '"').replace(/&#x27;|&#39;/g, '\'').replace(/&amp;/g, '&');
102
70
  };
71
+ const normalize = question => ({
72
+ ..._defaults.default,
73
+ ...question
74
+ });
103
75
 
104
- var normalize = function normalize(question) {
105
- return _objectSpread(_objectSpread({}, _defaults["default"]), question);
106
- };
107
76
  /**
108
77
  *
109
78
  * @param {*} question
110
79
  * @param {*} session
111
80
  * @param {*} env
112
81
  */
113
-
114
-
115
82
  exports.normalize = normalize;
116
-
117
- function model(question, session, env) {
118
- return new Promise( /*#__PURE__*/function () {
119
- var _ref = (0, _asyncToGenerator2["default"])( /*#__PURE__*/_regenerator["default"].mark(function _callee(resolve) {
120
- var normalizedQuestion, defaultFeedback, prepareChoiceFn, choices, _ref2, _ref2$value, value, feedback, showNote, note, _normalizedQuestion$m, maxLengthPerChoice, maxLengthPerChoiceEnabled, undefinedLengths, out;
121
-
122
- return _regenerator["default"].wrap(function _callee$(_context) {
123
- while (1) {
124
- switch (_context.prev = _context.next) {
125
- case 0:
126
- // this was added to treat an exception, when the model has choices without
127
- // the "value" property like: { label: 'test' }
128
- if (question.choices) {
129
- Object.keys(question.choices).forEach(function (key) {
130
- question.choices[key] = (question.choices[key] || []).map(function (item, index) {
131
- if (!item.value) {
132
- log('Choice does not contain "value" property, which is required.', item);
133
- return _objectSpread({
134
- value: "".concat(index)
135
- }, item);
136
- }
137
-
138
- return item;
139
- });
140
- });
141
- }
142
-
143
- normalizedQuestion = normalize(question);
144
- defaultFeedback = Object.assign({
145
- correct: 'Correct',
146
- incorrect: 'Incorrect'
147
- }, normalizedQuestion.defaultFeedback);
148
- prepareChoiceFn = prepareChoice(env.mode, defaultFeedback);
149
- choices = (0, _reduce["default"])(normalizedQuestion.choices, function (obj, area, key) {
150
- obj[key] = (0, _map["default"])(area, prepareChoiceFn);
151
- return obj;
152
- }, {});
153
- _ref2 = session || {}, _ref2$value = _ref2.value, value = _ref2$value === void 0 ? {} : _ref2$value;
154
- feedback = env.mode === 'evaluate' ? (0, _reduce["default"])(normalizedQuestion.choices, function (obj, respArea, key) {
155
- var chosenValue = value && value[key];
156
- var val = !(0, _isEmpty["default"])(chosenValue) && (0, _find["default"])(respArea, function (c) {
157
- return prepareVal(c.label) === prepareVal(chosenValue);
158
- });
159
- obj[key] = getFeedback(val);
160
- return obj;
161
- }, {}) : {}; // check if at least one choice has an alternate
162
-
163
- showNote = Object.values(choices).some(function (choice) {
164
- return (choice === null || choice === void 0 ? void 0 : choice.length) > 1;
165
- });
166
- note = normalizedQuestion.note || translator.t('common:commonCorrectAnswerWithAlternates', {
167
- lng: normalizedQuestion.language
168
- });
169
- _normalizedQuestion$m = normalizedQuestion.maxLengthPerChoice, maxLengthPerChoice = _normalizedQuestion$m === void 0 ? [] : _normalizedQuestion$m, maxLengthPerChoiceEnabled = normalizedQuestion.maxLengthPerChoiceEnabled;
170
- undefinedLengths = !maxLengthPerChoice.length; // calculate maxLengthPerChoice array if it is not defined or defined incorrectly
171
-
172
- Object.values(choices).forEach(function (choice, index) {
173
- var labelLengthsArr = (choice || []).map(function (choice) {
174
- return decodeHtmlEntities(choice.label || '').length;
175
- });
176
- var length = Math.max.apply(Math, (0, _toConsumableArray2["default"])(labelLengthsArr));
177
-
178
- if (undefinedLengths || !maxLengthPerChoice[index] || maxLengthPerChoice[index] < length || maxLengthPerChoice[index] > length + 10) {
179
- maxLengthPerChoice[index] = getAdjustedLength(length);
180
- }
181
- });
182
- out = {
183
- choices: choices,
184
- disabled: env.mode !== 'gather',
185
- displayType: normalizedQuestion.displayType,
186
- mode: env.mode,
187
- role: env.role,
188
- feedback: feedback,
189
- language: normalizedQuestion.language,
190
- markup: normalizedQuestion.markup,
191
- maxLengthPerChoice: maxLengthPerChoice,
192
- maxLengthPerChoiceEnabled: maxLengthPerChoiceEnabled,
193
- note: note,
194
- playerSpellCheckEnabled: normalizedQuestion.playerSpellCheckEnabled,
195
- prompt: normalizedQuestion.promptEnabled ? normalizedQuestion.prompt : _defaults["default"].prompt,
196
- rationale: _defaults["default"].rationale,
197
- responseCorrect: env.mode === 'evaluate' ? getScore(normalizedQuestion, session) === 1 : undefined,
198
- showNote: showNote,
199
- teacherInstructions: _defaults["default"].teacherInstructions,
200
- responseAreaInputConfiguration: normalizedQuestion.responseAreaInputConfiguration,
201
- extraCSSRules: normalizedQuestion.extraCSSRules
202
- };
203
-
204
- if (env.role === 'instructor' && (env.mode === 'view' || env.mode === 'evaluate')) {
205
- out.rationale = normalizedQuestion.rationaleEnabled ? normalizedQuestion.rationale : _defaults["default"].rationale;
206
- out.teacherInstructions = normalizedQuestion.teacherInstructionsEnabled ? normalizedQuestion.teacherInstructions : _defaults["default"].teacherInstructions;
207
- }
208
-
209
- resolve(out);
210
-
211
- case 15:
212
- case "end":
213
- return _context.stop();
214
- }
83
+ async function model(question, session, env) {
84
+ // this was added to treat an exception, when the model has choices without
85
+ // the "value" property like: { label: 'test' }
86
+ if (question.choices) {
87
+ Object.keys(question.choices).forEach(key => {
88
+ question.choices[key] = (question.choices[key] || []).map((item, index) => {
89
+ if (!item.value) {
90
+ log('Choice does not contain "value" property, which is required.', item);
91
+ return {
92
+ value: `${index}`,
93
+ ...item
94
+ };
215
95
  }
216
- }, _callee);
217
- }));
218
-
219
- return function (_x) {
220
- return _ref.apply(this, arguments);
221
- };
222
- }());
96
+ return item;
97
+ });
98
+ });
99
+ }
100
+ const normalizedQuestion = normalize(question);
101
+ const defaultFeedback = Object.assign({
102
+ correct: 'Correct',
103
+ incorrect: 'Incorrect'
104
+ }, normalizedQuestion.defaultFeedback);
105
+ const prepareChoiceFn = prepareChoice(env.mode, defaultFeedback);
106
+ const choices = (0, _reduce.default)(normalizedQuestion.choices, (obj, area, key) => {
107
+ obj[key] = (0, _map.default)(area, prepareChoiceFn);
108
+ return obj;
109
+ }, {});
110
+ const {
111
+ value = {}
112
+ } = session || {};
113
+ const feedback = env.mode === 'evaluate' ? (0, _reduce.default)(normalizedQuestion.choices, (obj, respArea, key) => {
114
+ const chosenValue = value && value[key];
115
+ const val = !(0, _isEmpty.default)(chosenValue) && (0, _find.default)(respArea, c => prepareVal(c.label) === prepareVal(chosenValue));
116
+ obj[key] = getFeedback(val);
117
+ return obj;
118
+ }, {}) : {};
119
+
120
+ // check if at least one choice has an alternate
121
+ const showNote = Object.values(choices).some(choice => choice?.length > 1);
122
+ const note = normalizedQuestion.note || translator.t('common:commonCorrectAnswerWithAlternates', {
123
+ lng: normalizedQuestion.language
124
+ });
125
+ const {
126
+ maxLengthPerChoice = [],
127
+ maxLengthPerChoiceEnabled
128
+ } = normalizedQuestion;
129
+ const undefinedLengths = !maxLengthPerChoice.length;
130
+
131
+ // calculate maxLengthPerChoice array if it is not defined or defined incorrectly
132
+ Object.values(choices).forEach((choice, index) => {
133
+ const labelLengthsArr = (choice || []).map(choice => decodeHtmlEntities(choice.label || '').length);
134
+ const length = Math.max(...labelLengthsArr);
135
+ if (undefinedLengths || !maxLengthPerChoice[index] || maxLengthPerChoice[index] < length || maxLengthPerChoice[index] > length + 10) {
136
+ maxLengthPerChoice[index] = getAdjustedLength(length);
137
+ }
138
+ });
139
+ const out = {
140
+ choices,
141
+ disabled: env.mode !== 'gather',
142
+ displayType: normalizedQuestion.displayType,
143
+ mode: env.mode,
144
+ role: env.role,
145
+ feedback,
146
+ language: normalizedQuestion.language,
147
+ markup: normalizedQuestion.markup,
148
+ maxLengthPerChoice,
149
+ maxLengthPerChoiceEnabled,
150
+ note,
151
+ playerSpellCheckEnabled: normalizedQuestion.playerSpellCheckEnabled,
152
+ prompt: normalizedQuestion.promptEnabled ? normalizedQuestion.prompt : _defaults.default.prompt,
153
+ rationale: _defaults.default.rationale,
154
+ responseCorrect: env.mode === 'evaluate' ? getScore(normalizedQuestion, session) === 1 : undefined,
155
+ showNote,
156
+ teacherInstructions: _defaults.default.teacherInstructions,
157
+ responseAreaInputConfiguration: normalizedQuestion.responseAreaInputConfiguration,
158
+ extraCSSRules: normalizedQuestion.extraCSSRules
159
+ };
160
+ if (env.role === 'instructor' && (env.mode === 'view' || env.mode === 'evaluate')) {
161
+ out.rationale = normalizedQuestion.rationaleEnabled ? normalizedQuestion.rationale : _defaults.default.rationale;
162
+ out.teacherInstructions = normalizedQuestion.teacherInstructionsEnabled ? normalizedQuestion.teacherInstructions : _defaults.default.teacherInstructions;
163
+ }
164
+ return out;
223
165
  }
224
-
225
- var prepareVal = function prepareVal(html) {
166
+ const prepareVal = html => {
226
167
  return decodeHTML(getInnerText(html).trim());
227
168
  };
228
-
229
169
  exports.prepareVal = prepareVal;
230
-
231
- var getScore = function getScore(config, session) {
232
- var _ref3 = session || {},
233
- value = _ref3.value;
234
-
235
- if (!session || (0, _isEmpty["default"])(session) || !value) {
170
+ const getScore = (config, session) => {
171
+ const {
172
+ value
173
+ } = session || {};
174
+ if (!session || (0, _isEmpty.default)(session) || !value) {
236
175
  return 0;
237
176
  }
238
-
239
- var responseAreas = config.markup && config.markup.match(/\{\{(.+?)\}\}/g);
240
- var maxScore = responseAreas ? responseAreas.length : 0;
241
- var correctCount = (0, _reduce["default"])(config.choices, function (total, respArea, key) {
242
- var chosenValue = value && value[key];
243
-
244
- if ((0, _isEmpty["default"])(chosenValue) || !(0, _find["default"])(respArea, function (c) {
245
- return prepareVal(c.label) === prepareVal(chosenValue);
246
- })) {
177
+ const responseAreas = config.markup && config.markup.match(/\{\{(.+?)\}\}/g);
178
+ const maxScore = responseAreas ? responseAreas.length : 0;
179
+ const correctCount = (0, _reduce.default)(config.choices, (total, respArea, key) => {
180
+ const chosenValue = value && value[key];
181
+ if ((0, _isEmpty.default)(chosenValue) || !(0, _find.default)(respArea, c => prepareVal(c.label) === prepareVal(chosenValue))) {
247
182
  return total;
248
183
  }
249
-
250
184
  return total + 1;
251
185
  }, 0);
252
- var str = maxScore ? (correctCount / maxScore).toFixed(2) : 0;
186
+ const str = maxScore ? (correctCount / maxScore).toFixed(2) : 0;
253
187
  return parseFloat(str);
254
188
  };
189
+
255
190
  /**
256
191
  * The score is partial by default for checkbox mode, allOrNothing for radio mode.
257
192
  * To disable partial scoring for checkbox mode you either set model.partialScoring = false or env.partialScoring =
@@ -263,50 +198,44 @@ var getScore = function getScore(config, session) {
263
198
  * @param {boolean} env.partialScoring - is partial scoring enabled (if undefined default to true) This overrides
264
199
  * `model.partialScoring`.
265
200
  */
266
-
267
-
268
201
  exports.getScore = getScore;
269
-
270
- function outcome(model, session) {
271
- var env = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
272
- return new Promise(function (resolve) {
273
- var partialScoringEnabled = _controllerUtils.partialScoring.enabled(model, env);
274
-
275
- var score = getScore(model, session);
202
+ function outcome(model, session, env = {}) {
203
+ return new Promise(resolve => {
204
+ const partialScoringEnabled = _controllerUtils.partialScoring.enabled(model, env);
205
+ const score = getScore(model, session);
276
206
  resolve({
277
207
  score: partialScoringEnabled ? score : score === 1 ? 1 : 0,
278
- empty: (0, _isEmpty["default"])(session)
208
+ empty: (0, _isEmpty.default)(session)
279
209
  });
280
210
  });
281
211
  }
282
-
283
- var createCorrectResponseSession = function createCorrectResponseSession(question, env) {
284
- return new Promise(function (resolve) {
212
+ const createCorrectResponseSession = (question, env) => {
213
+ return new Promise(resolve => {
285
214
  if (env.mode !== 'evaluate' && env.role === 'instructor') {
286
- var choices = question.choices;
287
- var value = {};
288
- Object.keys(choices).forEach(function (key, i) {
215
+ const {
216
+ choices
217
+ } = question;
218
+ const value = {};
219
+ Object.keys(choices).forEach((key, i) => {
289
220
  value[i] = choices[key][0].label;
290
221
  });
291
222
  resolve({
292
223
  id: '1',
293
- value: value
224
+ value
294
225
  });
295
226
  } else {
296
227
  resolve(null);
297
228
  }
298
229
  });
299
- }; // remove all html tags
300
- // const getInnerText = (html) => (html || '').replaceAll(/<[^>]*>/g, '');
301
-
230
+ };
302
231
 
232
+ // remove all html tags
233
+ // const getInnerText = (html) => (html || '').replaceAll(/<[^>]*>/g, '');
303
234
  exports.createCorrectResponseSession = createCorrectResponseSession;
304
-
305
- var getInnerText = function getInnerText(html) {
235
+ const getInnerText = html => {
306
236
  if (typeof html !== 'string') {
307
237
  return '';
308
238
  }
309
-
310
239
  if (typeof html.replaceAll === 'function') {
311
240
  return html.replaceAll(/<[^>]*>/g, '');
312
241
  } else {
@@ -314,73 +243,56 @@ var getInnerText = function getInnerText(html) {
314
243
  return html.replace(/<[^>]*>/g, '');
315
244
  }
316
245
  };
317
-
318
- var decodeHTML = function decodeHTML(html) {
319
- return (0, _he.decode)(html);
320
- }; // remove all html tags except img, iframe and source tag for audio
321
-
322
-
323
- var getContent = function getContent(html) {
324
- return (html || '').replace(/(<(?!img|iframe|source)([^>]+)>)/gi, '');
325
- };
326
-
327
- var validate = function validate() {
328
- var model = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
329
- var config = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
330
- var choices = model.choices,
331
- markup = model.markup;
332
- var maxResponseAreas = config.maxResponseAreas;
333
- var allChoicesErrors = {};
334
- var errors = {};
335
- ['teacherInstructions', 'prompt', 'rationale'].forEach(function (field) {
336
- var _config$field;
337
-
338
- if ((_config$field = config[field]) !== null && _config$field !== void 0 && _config$field.required && !getContent(model[field])) {
246
+ const decodeHTML = html => (0, _he.decode)(html);
247
+
248
+ // remove all html tags except img, iframe and source tag for audio
249
+ const getContent = html => (html || '').replace(/(<(?!img|iframe|source)([^>]+)>)/gi, '');
250
+ const validate = (model = {}, config = {}) => {
251
+ const {
252
+ choices,
253
+ markup
254
+ } = model;
255
+ const {
256
+ maxResponseAreas
257
+ } = config;
258
+ const allChoicesErrors = {};
259
+ const errors = {};
260
+ ['teacherInstructions', 'prompt', 'rationale'].forEach(field => {
261
+ if (config[field]?.required && !getContent(model[field])) {
339
262
  errors[field] = 'This field is required.';
340
263
  }
341
264
  });
342
- Object.entries(choices || {}).forEach(function (_ref4) {
343
- var _ref5 = (0, _slicedToArray2["default"])(_ref4, 2),
344
- key = _ref5[0],
345
- values = _ref5[1];
346
-
347
- var reversedChoices = (0, _toConsumableArray2["default"])(values || []).reverse();
348
- var choicesErrors = {};
349
- reversedChoices.forEach(function (choice, index) {
350
- var value = choice.value,
351
- label = choice.label;
352
-
265
+ Object.entries(choices || {}).forEach(([key, values]) => {
266
+ const reversedChoices = [...(values || [])].reverse();
267
+ const choicesErrors = {};
268
+ reversedChoices.forEach((choice, index) => {
269
+ const {
270
+ value,
271
+ label
272
+ } = choice;
353
273
  if (label === '' || label === '<div></div>') {
354
274
  choicesErrors[value] = 'Content should not be empty.';
355
275
  } else {
356
- var identicalAnswer = reversedChoices.slice(index + 1).some(function (c) {
357
- return c.label === label;
358
- });
359
-
276
+ const identicalAnswer = reversedChoices.slice(index + 1).some(c => c.label === label);
360
277
  if (identicalAnswer) {
361
278
  choicesErrors[value] = 'Content should be unique.';
362
279
  }
363
280
  }
364
281
  });
365
-
366
- if (!(0, _isEmpty["default"])(choicesErrors)) {
282
+ if (!(0, _isEmpty.default)(choicesErrors)) {
367
283
  allChoicesErrors[key] = choicesErrors;
368
284
  }
369
285
  });
370
- var nbOfResponseAreas = (markup.match(/\{\{(\d+)\}\}/g) || []).length;
371
-
286
+ const nbOfResponseAreas = (markup.match(/\{\{(\d+)\}\}/g) || []).length;
372
287
  if (nbOfResponseAreas > maxResponseAreas) {
373
- errors.responseAreas = "No more than ".concat(maxResponseAreas, " response areas should be defined.");
288
+ errors.responseAreas = `No more than ${maxResponseAreas} response areas should be defined.`;
374
289
  } else if (nbOfResponseAreas < 1) {
375
290
  errors.responseAreas = 'There should be at least 1 response area defined.';
376
291
  }
377
-
378
- if (!(0, _isEmpty["default"])(allChoicesErrors)) {
292
+ if (!(0, _isEmpty.default)(allChoicesErrors)) {
379
293
  errors.choices = allChoicesErrors;
380
294
  }
381
-
382
295
  return errors;
383
296
  };
384
-
385
297
  exports.validate = validate;
386
298
  //# sourceMappingURL=index.js.map