@pie-element/math-inline 5.6.1 → 5.6.4-next.1014

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.
@@ -2,12 +2,19 @@
2
2
 
3
3
  var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
4
 
5
+ var _typeof = require("@babel/runtime/helpers/typeof");
6
+
5
7
  Object.defineProperty(exports, "__esModule", {
6
8
  value: true
7
9
  });
10
+ exports.createCorrectResponseSession = void 0;
8
11
  exports.createDefaultModel = createDefaultModel;
9
12
  exports.model = model;
10
- exports.createCorrectResponseSession = exports.normalize = exports.outcome = void 0;
13
+ exports.validate = exports.outcome = exports.normalize = void 0;
14
+
15
+ var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
16
+
17
+ var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
11
18
 
12
19
  var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties"));
13
20
 
@@ -19,59 +26,23 @@ var _isEmpty = _interopRequireDefault(require("lodash/isEmpty"));
19
26
 
20
27
  var _feedback = require("@pie-lib/feedback");
21
28
 
22
- var _mathEvaluator = _interopRequireDefault(require("@pie-lib/math-evaluator"));
23
-
24
29
  var _utils = require("./utils");
25
30
 
26
31
  var _defaults = _interopRequireDefault(require("./defaults"));
27
32
 
28
- function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
33
+ var mv = _interopRequireWildcard(require("@pie-framework/math-validation"));
29
34
 
30
- function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2["default"])(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
35
+ var _excluded = ["responses"];
31
36
 
32
- var log = (0, _debug["default"])('@pie-element:math-inline:controller');
33
- var decimalRegex = /\.|,/g;
34
- var decimalCommaRegex = /,/g;
35
- var textRegex = /\\text\{([^{}]+)\}/g;
36
- var decimalWithThousandSeparatorNumberRegex = /^(?!0+\.00)(?=.{1,9}(\.|$))(?!0(?!\.))\d{1,3}(,\d{3})*(\.\d+)?$/;
37
- var noNumbers = /[^0-9.,]+/g;
38
- /**
39
- * TODO:
40
- *
41
- * We have `stringCheck` which if true disabled 'literal' and 'symbolic' so really it should be a validation method. And if it is what's the difference between it and 'literal'?
42
- *
43
- * We should support a equivalence option per correct response like:
44
- * responses: [ { answer: '..', validation: 'symbolic', alternates: [{ value: '..', validation: 'stringCompare'}, 'abc'] } ]
45
- *
46
- * if option is a string it is turned into an object w/ inherited opts.
47
- *
48
- * This would override any shared setting at the root.
49
- */
50
-
51
- function processAnswerItem() {
52
- var answerItem = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
53
- var isLiteral = arguments.length > 1 ? arguments[1] : undefined;
54
- // looks confusing, but we're replacing U+002D and U+2212 (minus and hyphen) so we have the same symbol everywhere consistently
55
- // further processing is to be added here if needed
56
- var newAnswerItem = answerItem.replace('−', '-');
57
- newAnswerItem = newAnswerItem.replace(/\\cdot/g, '\\times'); // also ignore text nodes, just swap out with empty string
58
-
59
- newAnswerItem = newAnswerItem.replace(textRegex, '');
60
-
61
- if (containsDecimal(newAnswerItem) && validExpressionWithThousandSeparator(newAnswerItem)) {
62
- newAnswerItem = newAnswerItem.replace(decimalCommaRegex, '');
63
- }
37
+ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
64
38
 
65
- newAnswerItem = newAnswerItem.replace(/\\ /g, '').replace(/ /g, ''); // eslint-disable-next-line no-useless-escape
39
+ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
66
40
 
67
- newAnswerItem = newAnswerItem.replace(/\\%/g, '').replace(/%/g, '');
68
- return isLiteral ? stripForStringCompare(newAnswerItem) : newAnswerItem;
69
- }
41
+ 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; }
70
42
 
71
- function containsDecimal() {
72
- var expression = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
73
- return expression.match(decimalRegex);
74
- }
43
+ 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; }
44
+
45
+ var log = (0, _debug["default"])('@pie-element:math-inline:controller');
75
46
 
76
47
  var getResponseCorrectness = function getResponseCorrectness(model, answerItem, isOutcome) {
77
48
  var correctResponses = model.responses;
@@ -101,84 +72,36 @@ var getResponseCorrectness = function getResponseCorrectness(model, answerItem,
101
72
  return correctnessObject;
102
73
  };
103
74
 
104
- var stripTargets = [/{/g, /}/g, /\[/g, /]/g, /\\ /g, /\\/g, /\\s/g, /left/g, /right/g, / /g];
105
-
106
- var validExpressionWithThousandSeparator = function validExpressionWithThousandSeparator(answer) {
107
- var numericValues = answer.split(noNumbers);
108
-
109
- for (var i = 0; i < numericValues.length; i++) {
110
- if (numericValues[i] != '' && containsDecimal(numericValues[i]) && !decimalWithThousandSeparatorNumberRegex.test(numericValues[i])) {
111
- return false;
112
- }
113
- }
114
-
115
- return true;
116
- };
117
-
118
- function stripForStringCompare() {
119
- var answer = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
120
- var stripped = answer;
121
- stripTargets.forEach(function (stripTarget) {
122
- return stripped = stripped.replace(stripTarget, '');
123
- });
124
- return stripped;
125
- }
126
-
127
- function handleStringBasedCheck(acceptedValues, answerItem) {
128
- var answerValueToUse = processAnswerItem(answerItem, true);
75
+ function getIsAnswerCorrect(correctResponseItem, answerItem) {
129
76
  var answerCorrect = false;
77
+ (correctResponseItem || []).forEach(function (correctResponse) {
78
+ var opts = {
79
+ mode: correctResponse.validation || _defaults["default"].validationDefault
80
+ };
130
81
 
131
- for (var i = 0; i < acceptedValues.length; i++) {
132
- var acceptedValueToUse = processAnswerItem(acceptedValues[i], true);
133
- answerCorrect = answerValueToUse === acceptedValueToUse;
134
-
135
- if (answerCorrect === true) {
136
- break;
82
+ if (opts.mode == 'literal') {
83
+ opts.literal = {
84
+ allowTrailingZeros: correctResponse.allowTrailingZeros || false,
85
+ ignoreOrder: correctResponse.ignoreOrder || false
86
+ };
137
87
  }
138
- }
139
88
 
140
- return answerCorrect;
141
- }
142
-
143
- function getIsAnswerCorrect(correctResponseItem, answerItem) {
144
- var answerCorrect = false;
145
- correctResponseItem.forEach(function (correctResponse) {
146
- // if not already deemed correct for one of the correct responses
147
89
  if (!answerCorrect) {
148
90
  var acceptedValues = [correctResponse.answer].concat(Object.keys(correctResponse.alternates || {}).map(function (alternateId) {
149
91
  return correctResponse.alternates[alternateId];
150
- }));
92
+ })) || [];
151
93
 
152
- if (correctResponse.validation === 'literal') {
94
+ try {
153
95
  for (var i = 0; i < acceptedValues.length; i++) {
154
- var answerValueToUse = processAnswerItem(answerItem, true);
155
- var acceptedValueToUse = processAnswerItem(acceptedValues[i], true);
96
+ answerCorrect = mv.latexEqual(answerItem, acceptedValues[i], opts);
156
97
 
157
- if (acceptedValueToUse === answerValueToUse) {
158
- answerCorrect = true;
98
+ if (answerCorrect) {
159
99
  break;
160
100
  }
161
101
  }
162
- } else {
163
- try {
164
- for (var _i = 0; _i < acceptedValues.length; _i++) {
165
- // let answerValueToUse = processAnswerItem(answerItem);
166
- // let acceptedValueToUse = processAnswerItem(acceptedValues[i]);
167
- answerCorrect = (0, _mathEvaluator["default"])(processAnswerItem(acceptedValues[_i]), processAnswerItem(answerItem), {
168
- isLatex: true,
169
- allowThousandsSeparator: correctResponse.allowThousandsSeparator
170
- });
171
-
172
- if (answerCorrect) {
173
- break;
174
- }
175
- }
176
- } catch (e) {
177
- log('Parse failure when evaluating math', e, correctResponse, answerItem); // try to string check compare, last resort?
178
- // once invalid models have been weeded out, this'll get removed.
179
-
180
- answerCorrect = handleStringBasedCheck(acceptedValues, answerItem);
181
- }
102
+ } catch (e) {
103
+ log('Parse failure when evaluating math', e, correctResponse, answerItem);
104
+ answerCorrect = false;
182
105
  }
183
106
  }
184
107
  });
@@ -226,7 +149,18 @@ var outcome = function outcome(question, session, env) {
226
149
  exports.outcome = outcome;
227
150
 
228
151
  var normalize = function normalize(question) {
229
- return _objectSpread({
152
+ // making sure that defaults are set
153
+ if (!(0, _isEmpty["default"])(question.responses)) {
154
+ question.responses = question.responses.map(function (correctResponse) {
155
+ return _objectSpread(_objectSpread({}, correctResponse), {}, {
156
+ validation: correctResponse.validation || question.validationDefault,
157
+ allowTrailingZeros: correctResponse.allowTrailingZeros || question.allowTrailingZerosDefault,
158
+ ignoreOrder: correctResponse.ignoreOrder || question.ignoreOrderDefault
159
+ });
160
+ });
161
+ }
162
+
163
+ return _objectSpread(_objectSpread({}, _defaults["default"]), {}, {
230
164
  feedbackEnabled: true,
231
165
  promptEnabled: true,
232
166
  rationaleEnabled: true,
@@ -241,14 +175,14 @@ function model(question, session, env) {
241
175
  return new Promise(function (resolve) {
242
176
  var normalizedQuestion = normalize(question);
243
177
  var correctness = getCorrectness(normalizedQuestion, env, session);
244
- var correctResponse = {};
245
178
  var responses = normalizedQuestion.responses,
246
- config = (0, _objectWithoutProperties2["default"])(normalizedQuestion, ["responses"]);
179
+ config = (0, _objectWithoutProperties2["default"])(normalizedQuestion, _excluded);
247
180
 
248
181
  if (config.responseType === _utils.ResponseTypes.simple) {
249
182
  config.responses = responses.slice(0, 1);
250
183
  } else {
251
184
  config.responses = responses;
185
+ config.customKeys = [];
252
186
  }
253
187
 
254
188
  var fb = env.mode === 'evaluate' && normalizedQuestion.feedbackEnabled ? (0, _feedback.getFeedbackForCorrectness)(correctness, normalizedQuestion.feedback) : Promise.resolve(undefined);
@@ -260,15 +194,21 @@ function model(question, session, env) {
260
194
  disabled: env.mode !== 'gather',
261
195
  view: env.mode === 'view'
262
196
  };
263
- var out;
197
+ var out = base;
198
+ var showNote = false;
199
+ (config && config.responses || []).forEach(function (response) {
200
+ if (response.validation === 'symbolic' || Object.keys(response.alternates || {}).length > 0) {
201
+ showNote = true;
202
+ return;
203
+ }
204
+ });
264
205
 
265
206
  if (env.mode === 'evaluate') {
266
- out = Object.assign(base, {
267
- correctResponse: correctResponse
268
- });
207
+ out.correctResponse = {};
208
+ out.config.showNote = showNote;
269
209
  } else {
270
- out = base;
271
210
  out.config.responses = [];
211
+ out.config.showNote = false;
272
212
  }
273
213
 
274
214
  if (env.role === 'instructor' && (env.mode === 'view' || env.mode === 'evaluate')) {
@@ -281,6 +221,7 @@ function model(question, session, env) {
281
221
  out.config.teacherInstructions = null;
282
222
  }
283
223
 
224
+ out.config.env = env;
284
225
  out.config.prompt = normalizedQuestion.promptEnabled ? normalizedQuestion.prompt : null;
285
226
  log('out: ', out);
286
227
  resolve(out);
@@ -295,26 +236,37 @@ var escape = function escape(string) {
295
236
 
296
237
  var simpleSessionResponse = function simpleSessionResponse(question) {
297
238
  return new Promise(function (resolve) {
298
- var responses = question.responses;
239
+ var responses = question.responses,
240
+ id = question.id;
299
241
 
300
- var _ref = responses ? responses[0] : {},
242
+ var _ref = responses && responses.length ? responses[0] : {},
301
243
  answer = _ref.answer;
302
244
 
303
245
  resolve({
304
- id: question.id,
305
- response: answer,
306
- completeAnswer: answer
246
+ id: id,
247
+ response: answer || '',
248
+ completeAnswer: answer || ''
307
249
  });
308
250
  });
309
251
  };
310
252
 
311
253
  var advancedSessionResponse = function advancedSessionResponse(question) {
312
254
  return new Promise(function (resolve, reject) {
313
- var responses = question.responses;
255
+ var responses = question.responses,
256
+ id = question.id;
314
257
 
315
- var _ref2 = responses ? responses[0] : {},
258
+ var _ref2 = responses && responses.length ? responses[0] : {},
316
259
  answer = _ref2.answer;
317
260
 
261
+ if (!answer) {
262
+ resolve({
263
+ id: id,
264
+ answers: {},
265
+ completeAnswer: ''
266
+ });
267
+ return;
268
+ }
269
+
318
270
  try {
319
271
  var e = question.expression;
320
272
  var RESPONSE_TOKEN = /\\{\\{\s*response\s*\\}\\}/g;
@@ -330,9 +282,9 @@ var advancedSessionResponse = function advancedSessionResponse(question) {
330
282
 
331
283
  if (!m) {
332
284
  resolve({
285
+ id: id,
333
286
  answers: {},
334
- completeAnswer: answer,
335
- id: question.id
287
+ completeAnswer: answer
336
288
  });
337
289
  console.log("can not find match: ".concat(o, " in ").concat(answer));
338
290
  return;
@@ -348,15 +300,15 @@ var advancedSessionResponse = function advancedSessionResponse(question) {
348
300
  }
349
301
 
350
302
  resolve({
303
+ id: id,
351
304
  answers: answers,
352
- completeAnswer: answer,
353
- id: question.id
305
+ completeAnswer: answer
354
306
  });
355
307
  } catch (e) {
356
308
  resolve({
309
+ id: id,
357
310
  answers: {},
358
- completeAnswer: answer,
359
- id: question.id
311
+ completeAnswer: answer
360
312
  });
361
313
  console.error(e.toString());
362
314
  }
@@ -378,4 +330,69 @@ var createCorrectResponseSession = function createCorrectResponseSession(questio
378
330
  };
379
331
 
380
332
  exports.createCorrectResponseSession = createCorrectResponseSession;
333
+
334
+ var validate = function validate() {
335
+ var model = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
336
+ var config = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
337
+ var _model$expression = model.expression,
338
+ expression = _model$expression === void 0 ? '' : _model$expression,
339
+ responses = model.responses,
340
+ responseType = model.responseType;
341
+ var maxResponseAreas = config.maxResponseAreas;
342
+ var responsesErrors = {};
343
+ (responses || []).forEach(function (response, index) {
344
+ var answer = response.answer;
345
+ var reversedAlternates = (0, _toConsumableArray2["default"])(Object.entries(response.alternates || {})).reverse();
346
+ var alternatesErrors = {};
347
+ var responseError = {};
348
+
349
+ if (answer === '') {
350
+ responseError.answer = 'Content should not be empty.';
351
+ }
352
+
353
+ reversedAlternates.forEach(function (_ref3, index) {
354
+ var _ref4 = (0, _slicedToArray2["default"])(_ref3, 2),
355
+ key = _ref4[0],
356
+ value = _ref4[1];
357
+
358
+ if (value === '') {
359
+ alternatesErrors[key] = 'Content should not be empty.';
360
+ } else {
361
+ var identicalAnswer = answer === value || reversedAlternates.slice(index + 1).some(function (_ref5) {
362
+ var _ref6 = (0, _slicedToArray2["default"])(_ref5, 2),
363
+ val = _ref6[1];
364
+
365
+ return val === value;
366
+ });
367
+
368
+ if (identicalAnswer) {
369
+ alternatesErrors[key] = 'Content should be unique.';
370
+ }
371
+ }
372
+ });
373
+
374
+ if (!(0, _isEmpty["default"])(responseError) || !(0, _isEmpty["default"])(alternatesErrors)) {
375
+ responsesErrors[index] = _objectSpread(_objectSpread({}, responseError), alternatesErrors);
376
+ }
377
+ });
378
+ var errors = {};
379
+
380
+ if (responseType === 'Advanced Multi') {
381
+ var nbOfResponseAreas = (expression.match(/\{\{response\}\}/g) || []).length;
382
+
383
+ if (nbOfResponseAreas > maxResponseAreas) {
384
+ errors.responseAreasError = "No more than ".concat(maxResponseAreas, " response areas should be defined.");
385
+ } else if (nbOfResponseAreas < 1) {
386
+ errors.responseAreasError = 'There should be at least 1 response area defined.';
387
+ }
388
+ }
389
+
390
+ if (!(0, _isEmpty["default"])(responsesErrors)) {
391
+ errors.responsesErrors = responsesErrors;
392
+ }
393
+
394
+ return errors;
395
+ };
396
+
397
+ exports.validate = validate;
381
398
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.js"],"names":["log","decimalRegex","decimalCommaRegex","textRegex","decimalWithThousandSeparatorNumberRegex","noNumbers","processAnswerItem","answerItem","isLiteral","newAnswerItem","replace","containsDecimal","validExpressionWithThousandSeparator","stripForStringCompare","expression","match","getResponseCorrectness","model","isOutcome","correctResponses","responses","isAdvanced","responseType","ResponseTypes","advanced","correctness","score","correct","isAnswerCorrect","getIsAnswerCorrect","slice","correctnessObject","stripTargets","answer","numericValues","split","i","length","test","stripped","forEach","stripTarget","handleStringBasedCheck","acceptedValues","answerValueToUse","answerCorrect","acceptedValueToUse","correctResponseItem","correctResponse","concat","Object","keys","alternates","map","alternateId","validation","isLatex","allowThousandsSeparator","e","getCorrectness","question","env","session","mode","completeAnswer","response","createDefaultModel","Promise","resolve","config","defaults","outcome","undefined","completed","empty","normalize","feedbackEnabled","promptEnabled","rationaleEnabled","teacherInstructionsEnabled","studentInstructionsEnabled","normalizedQuestion","simple","fb","feedback","then","base","disabled","view","out","assign","role","rationale","teacherInstructions","prompt","escape","string","simpleSessionResponse","id","advancedSessionResponse","reject","RESPONSE_TOKEN","o","to","t","tt","join","m","RegExp","count","answers","console","shift","value","trim","error","toString","createCorrectResponseSession","toLowerCase"],"mappings":"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","sourcesContent":["import debug from 'debug';\nimport isEmpty from 'lodash/isEmpty';\nimport { getFeedbackForCorrectness } from '@pie-lib/feedback';\nimport areValuesEqual from '@pie-lib/math-evaluator';\nimport { ResponseTypes } from './utils';\n\nimport defaults from './defaults';\n\nconst log = debug('@pie-element:math-inline:controller');\nconst decimalRegex = /\\.|,/g;\nconst decimalCommaRegex = /,/g;\nconst textRegex = /\\\\text\\{([^{}]+)\\}/g;\nconst decimalWithThousandSeparatorNumberRegex = /^(?!0+\\.00)(?=.{1,9}(\\.|$))(?!0(?!\\.))\\d{1,3}(,\\d{3})*(\\.\\d+)?$/;\nconst noNumbers = /[^0-9.,]+/g;\n\n/**\n * TODO:\n *\n * We have `stringCheck` which if true disabled 'literal' and 'symbolic' so really it should be a validation method. And if it is what's the difference between it and 'literal'?\n *\n * We should support a equivalence option per correct response like:\n * responses: [ { answer: '..', validation: 'symbolic', alternates: [{ value: '..', validation: 'stringCompare'}, 'abc'] } ]\n *\n * if option is a string it is turned into an object w/ inherited opts.\n *\n * This would override any shared setting at the root.\n */\n\nfunction processAnswerItem(answerItem = '', isLiteral) {\n // looks confusing, but we're replacing U+002D and U+2212 (minus and hyphen) so we have the same symbol everywhere consistently\n // further processing is to be added here if needed\n let newAnswerItem = answerItem.replace('−', '-');\n\n newAnswerItem = newAnswerItem.replace(/\\\\cdot/g, '\\\\times');\n\n // also ignore text nodes, just swap out with empty string\n\n newAnswerItem = newAnswerItem.replace(textRegex, '');\n if (\n containsDecimal(newAnswerItem) && validExpressionWithThousandSeparator(newAnswerItem)\n ) {\n newAnswerItem = newAnswerItem.replace(decimalCommaRegex, '');\n }\n\n newAnswerItem = newAnswerItem.replace(/\\\\ /g, '').replace(/ /g, '');\n\n // eslint-disable-next-line no-useless-escape\n newAnswerItem = newAnswerItem\n .replace(/\\\\%/g, '')\n .replace(/%/g, '');\n\n return isLiteral ? stripForStringCompare(newAnswerItem) : newAnswerItem;\n}\n\nfunction containsDecimal(expression = '') {\n return expression.match(decimalRegex);\n}\n\nconst getResponseCorrectness = (model, answerItem, isOutcome) => {\n const correctResponses = model.responses;\n const isAdvanced = model.responseType === ResponseTypes.advanced;\n\n if (!answerItem) {\n return {\n correctness: 'unanswered',\n score: isOutcome ? 0 : '0%',\n correct: false\n };\n }\n\n const isAnswerCorrect = getIsAnswerCorrect(\n isAdvanced ? correctResponses : correctResponses.slice(0, 1),\n answerItem\n );\n const correctnessObject = {\n correctness: 'incorrect',\n score: isOutcome ? 0 : '0%',\n correct: false\n };\n\n if (isAnswerCorrect) {\n correctnessObject.correctness = 'correct';\n correctnessObject.score = isOutcome ? 1 : '100%';\n correctnessObject.correct = true;\n }\n\n return correctnessObject;\n};\n\nconst stripTargets = [\n /{/g,\n /}/g,\n /\\[/g,\n /]/g,\n /\\\\ /g,\n /\\\\/g,\n /\\\\s/g,\n /left/g,\n /right/g,\n / /g\n];\n\nconst validExpressionWithThousandSeparator = (answer) => {\n const numericValues = answer.split(noNumbers);\n\n for (let i = 0; i < numericValues.length; i++) {\n if (numericValues[i] != '' && containsDecimal(numericValues[i]) && !decimalWithThousandSeparatorNumberRegex.test(numericValues[i])) {\n\n return false;\n }\n }\n\n return true\n}\n\nfunction stripForStringCompare(answer = '') {\n let stripped = answer;\n\n stripTargets.forEach(stripTarget => {\n return (stripped = stripped.replace(stripTarget, ''));\n });\n\n return stripped;\n}\n\nfunction handleStringBasedCheck(acceptedValues, answerItem) {\n let answerValueToUse = processAnswerItem(answerItem, true);\n let answerCorrect = false;\n\n for (let i = 0; i < acceptedValues.length; i++) {\n let acceptedValueToUse = processAnswerItem(acceptedValues[i], true);\n\n answerCorrect = answerValueToUse === acceptedValueToUse;\n\n if (answerCorrect === true) {\n break;\n }\n }\n\n return answerCorrect;\n}\n\nfunction getIsAnswerCorrect(correctResponseItem, answerItem) {\n let answerCorrect = false;\n\n correctResponseItem.forEach(correctResponse => {\n // if not already deemed correct for one of the correct responses\n if (!answerCorrect) {\n const acceptedValues = [correctResponse.answer].concat(\n Object.keys(correctResponse.alternates || {}).map(\n alternateId => correctResponse.alternates[alternateId]\n )\n );\n\n if (correctResponse.validation === 'literal') {\n for (let i = 0; i < acceptedValues.length; i++) {\n let answerValueToUse = processAnswerItem(answerItem, true);\n let acceptedValueToUse = processAnswerItem(acceptedValues[i], true);\n\n if (acceptedValueToUse === answerValueToUse) {\n answerCorrect = true;\n break;\n }\n }\n } else {\n try {\n for (let i = 0; i < acceptedValues.length; i++) {\n // let answerValueToUse = processAnswerItem(answerItem);\n // let acceptedValueToUse = processAnswerItem(acceptedValues[i]);\n\n answerCorrect = areValuesEqual(\n processAnswerItem(acceptedValues[i]),\n processAnswerItem(answerItem),\n {\n isLatex: true,\n allowThousandsSeparator: correctResponse.allowThousandsSeparator\n }\n );\n if (answerCorrect) {\n break;\n }\n }\n } catch (e) {\n log(\n 'Parse failure when evaluating math',\n e,\n correctResponse,\n answerItem\n );\n // try to string check compare, last resort?\n // once invalid models have been weeded out, this'll get removed.\n answerCorrect = handleStringBasedCheck(acceptedValues, answerItem);\n }\n }\n }\n });\n\n return answerCorrect;\n}\n\nconst getCorrectness = (question, env, session, isOutcome) => {\n if (env.mode === 'evaluate') {\n return getResponseCorrectness(\n question,\n question.responseType === ResponseTypes.advanced\n ? (session && session.completeAnswer) || ''\n : session && session.response,\n isOutcome\n );\n }\n};\n\nexport function createDefaultModel(model = {}) {\n return new Promise(resolve => {\n resolve({\n config: {\n ...defaults,\n ...model\n }\n });\n });\n}\n\nexport const outcome = (question, session, env) => {\n return new Promise(resolve => {\n if (env.mode !== 'evaluate') {\n resolve({ score: undefined, completed: undefined });\n } else {\n if (!session || isEmpty(session)) {\n resolve({ score: 0, empty: true });\n } else {\n const correctness = getCorrectness(question, env, session, true);\n\n resolve({ score: correctness.score });\n }\n }\n });\n};\n\nexport const normalize = question => ({\n feedbackEnabled: true,\n promptEnabled: true,\n rationaleEnabled: true,\n teacherInstructionsEnabled: true,\n studentInstructionsEnabled: true,\n ...question\n});\n\nexport function model(question, session, env) {\n return new Promise(resolve => {\n const normalizedQuestion = normalize(question);\n const correctness = getCorrectness(normalizedQuestion, env, session);\n const correctResponse = {};\n const { responses, ...config } = normalizedQuestion;\n\n if (config.responseType === ResponseTypes.simple) {\n config.responses = responses.slice(0, 1);\n } else {\n config.responses = responses;\n }\n\n const fb =\n env.mode === 'evaluate' && normalizedQuestion.feedbackEnabled\n ? getFeedbackForCorrectness(correctness, normalizedQuestion.feedback)\n : Promise.resolve(undefined);\n\n fb.then(feedback => {\n const base = {\n config,\n correctness,\n feedback,\n disabled: env.mode !== 'gather',\n view: env.mode === 'view'\n };\n\n let out;\n\n if (env.mode === 'evaluate') {\n out = Object.assign(base, {\n correctResponse\n });\n } else {\n out = base;\n\n out.config.responses = [];\n }\n\n if (\n env.role === 'instructor' &&\n (env.mode === 'view' || env.mode === 'evaluate')\n ) {\n out.rationale = normalizedQuestion.rationaleEnabled\n ? normalizedQuestion.rationale\n : null;\n out.teacherInstructions = normalizedQuestion.teacherInstructionsEnabled\n ? normalizedQuestion.teacherInstructions\n : null;\n } else {\n out.rationale = null;\n out.teacherInstructions = null;\n out.config.rationale = null;\n out.config.teacherInstructions = null;\n }\n\n out.config.prompt = normalizedQuestion.promptEnabled\n ? normalizedQuestion.prompt\n : null;\n\n log('out: ', out);\n resolve(out);\n });\n });\n}\n\nconst escape = string => string.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&'); // $& means the whole matched string\n\nconst simpleSessionResponse = question =>\n new Promise(resolve => {\n const { responses } = question;\n const { answer } = responses ? responses[0] : {};\n resolve({\n id: question.id,\n response: answer,\n completeAnswer: answer\n });\n });\n\nconst advancedSessionResponse = question =>\n new Promise((resolve, reject) => {\n const { responses } = question;\n const { answer } = responses ? responses[0] : {};\n\n try {\n const e = question.expression;\n const RESPONSE_TOKEN = /\\\\{\\\\{\\s*response\\s*\\\\}\\\\}/g;\n\n const o = escape(e).split(RESPONSE_TOKEN);\n const to = o.map(t => (t === '' ? t : t.replace(/\\s+/g, () => ('\\\\s*'))));\n const tt = to.join('(.*)');\n\n const m = answer.match(new RegExp(tt));\n\n const count = o.length - 1;\n\n if (!m) {\n resolve({\n answers: {},\n completeAnswer: answer,\n id: question.id\n });\n\n console.log(`can not find match: ${o} in ${answer}`);\n\n return;\n }\n\n m.shift();\n\n const answers = {};\n\n for (var i = 0; i < count; i++) {\n answers[`r${i + 1}`] = { value: m[i].trim() };\n }\n\n resolve({\n answers,\n completeAnswer: answer,\n id: question.id\n });\n } catch (e) {\n resolve({\n answers: {},\n completeAnswer: answer,\n id: question.id\n });\n\n console.error(e.toString());\n }\n });\n\n\nexport const createCorrectResponseSession = (question, env) => {\n if (env.mode === 'evaluate' || env.role !== 'instructor') {\n // eslint-disable-next-line no-console\n console.error(\n 'can not create correct response session if mode is evaluate or role is not instructor'\n );\n\n return Promise.resolve(null);\n }\n\n if ((question.responseType || '').toLowerCase() === 'simple') {\n return simpleSessionResponse(question, env);\n } else {\n return advancedSessionResponse(question, env);\n }\n};\n"],"file":"index.js"}
1
+ {"version":3,"sources":["../src/index.js"],"names":["log","getResponseCorrectness","model","answerItem","isOutcome","correctResponses","responses","isAdvanced","responseType","ResponseTypes","advanced","correctness","score","correct","isAnswerCorrect","getIsAnswerCorrect","slice","correctnessObject","correctResponseItem","answerCorrect","forEach","correctResponse","opts","mode","validation","defaults","validationDefault","literal","allowTrailingZeros","ignoreOrder","acceptedValues","answer","concat","Object","keys","alternates","map","alternateId","i","length","mv","latexEqual","e","getCorrectness","question","env","session","completeAnswer","response","createDefaultModel","Promise","resolve","config","outcome","undefined","completed","empty","normalize","allowTrailingZerosDefault","ignoreOrderDefault","feedbackEnabled","promptEnabled","rationaleEnabled","teacherInstructionsEnabled","studentInstructionsEnabled","normalizedQuestion","simple","customKeys","fb","feedback","then","base","disabled","view","out","showNote","role","rationale","teacherInstructions","prompt","escape","string","replace","simpleSessionResponse","id","advancedSessionResponse","reject","answers","expression","RESPONSE_TOKEN","o","split","to","t","tt","join","m","match","RegExp","count","console","shift","value","trim","error","toString","createCorrectResponseSession","toLowerCase","validate","maxResponseAreas","responsesErrors","index","reversedAlternates","entries","reverse","alternatesErrors","responseError","key","identicalAnswer","some","val","errors","nbOfResponseAreas","responseAreasError"],"mappings":"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","sourcesContent":["import debug from 'debug';\nimport isEmpty from 'lodash/isEmpty';\nimport { getFeedbackForCorrectness } from '@pie-lib/feedback';\nimport { ResponseTypes } from './utils';\n\nimport defaults from './defaults';\n\nimport * as mv from '@pie-framework/math-validation';\n\n\nconst log = debug('@pie-element:math-inline:controller');\n\n\nconst getResponseCorrectness = (model, answerItem, isOutcome) => {\n const correctResponses = model.responses;\n const isAdvanced = model.responseType === ResponseTypes.advanced;\n\n if (!answerItem) {\n return {\n correctness: 'unanswered',\n score: isOutcome ? 0 : '0%',\n correct: false,\n };\n }\n\n const isAnswerCorrect = getIsAnswerCorrect(\n isAdvanced ? correctResponses : correctResponses.slice(0, 1),\n answerItem\n );\n\n const correctnessObject = {\n correctness: 'incorrect',\n score: isOutcome ? 0 : '0%',\n correct: false,\n };\n\n if (isAnswerCorrect) {\n correctnessObject.correctness = 'correct';\n correctnessObject.score = isOutcome ? 1 : '100%';\n correctnessObject.correct = true;\n }\n\n return correctnessObject;\n};\n\n\nfunction getIsAnswerCorrect(correctResponseItem, answerItem) {\n let answerCorrect = false;\n\n (correctResponseItem || []).forEach(correctResponse => {\n\n let opts = {\n mode: correctResponse.validation || defaults.validationDefault\n }\n\n if (opts.mode == 'literal') {\n opts.literal = {\n allowTrailingZeros: correctResponse.allowTrailingZeros || false,\n ignoreOrder: correctResponse.ignoreOrder || false,\n };\n }\n\n if (!answerCorrect) {\n const acceptedValues = [correctResponse.answer].concat(\n Object.keys(correctResponse.alternates || {}).map(\n alternateId => correctResponse.alternates[alternateId]\n )\n ) || [];\n\n try {\n for (let i = 0; i < acceptedValues.length; i++) {\n answerCorrect = mv.latexEqual(answerItem, acceptedValues[i], opts)\n\n if (answerCorrect) {\n break;\n }\n }\n } catch (e) {\n log(\n 'Parse failure when evaluating math',\n e,\n correctResponse,\n answerItem\n );\n\n answerCorrect = false;\n }\n }\n });\n\n return answerCorrect;\n}\n\nconst getCorrectness = (question, env, session, isOutcome) => {\n if (env.mode === 'evaluate') {\n return getResponseCorrectness(\n question,\n question.responseType === ResponseTypes.advanced\n ? (session && session.completeAnswer) || ''\n : session && session.response,\n isOutcome\n );\n }\n};\n\nexport function createDefaultModel(model = {}) {\n return new Promise((resolve) => {\n resolve({\n config: {\n ...defaults,\n ...model,\n },\n });\n });\n}\n\nexport const outcome = (question, session, env) => {\n return new Promise((resolve) => {\n if (env.mode !== 'evaluate') {\n resolve({ score: undefined, completed: undefined });\n } else {\n if (!session || isEmpty(session)) {\n resolve({ score: 0, empty: true });\n } else {\n const correctness = getCorrectness(question, env, session, true);\n\n resolve({ score: correctness.score });\n }\n }\n });\n};\n\nexport const normalize = (question) => {\n\n // making sure that defaults are set\n if (!isEmpty(question.responses)) {\n question.responses = question.responses.map(correctResponse => ({\n ...correctResponse, validation: correctResponse.validation || question.validationDefault,\n allowTrailingZeros: correctResponse.allowTrailingZeros || question.allowTrailingZerosDefault,\n ignoreOrder: correctResponse.ignoreOrder || question.ignoreOrderDefault\n }))\n }\n\n return {\n ...defaults,\n feedbackEnabled: true,\n promptEnabled: true,\n rationaleEnabled: true,\n teacherInstructionsEnabled: true,\n studentInstructionsEnabled: true,\n ...question,\n }\n}\n\nexport function model(question, session, env) {\n return new Promise((resolve) => {\n const normalizedQuestion = normalize(question);\n const correctness = getCorrectness(normalizedQuestion, env, session);\n const { responses, ...config } = normalizedQuestion;\n\n if (config.responseType === ResponseTypes.simple) {\n config.responses = responses.slice(0, 1);\n } else {\n config.responses = responses;\n config.customKeys = [];\n }\n\n const fb =\n env.mode === 'evaluate' && normalizedQuestion.feedbackEnabled\n ? getFeedbackForCorrectness(correctness, normalizedQuestion.feedback)\n : Promise.resolve(undefined);\n\n fb.then((feedback) => {\n const base = {\n config,\n correctness,\n feedback,\n disabled: env.mode !== 'gather',\n view: env.mode === 'view',\n };\n\n const out = base;\n let showNote = false;\n\n ((config && config.responses) || []).forEach((response) => {\n if (\n response.validation === 'symbolic' ||\n Object.keys(response.alternates || {}).length > 0\n ) {\n showNote = true;\n return;\n }\n });\n\n if (env.mode === 'evaluate') {\n out.correctResponse = {};\n out.config.showNote = showNote;\n } else {\n out.config.responses = [];\n out.config.showNote = false;\n }\n\n if (\n env.role === 'instructor' &&\n (env.mode === 'view' || env.mode === 'evaluate')\n ) {\n out.rationale = normalizedQuestion.rationaleEnabled\n ? normalizedQuestion.rationale\n : null;\n out.teacherInstructions = normalizedQuestion.teacherInstructionsEnabled\n ? normalizedQuestion.teacherInstructions\n : null;\n } else {\n out.rationale = null;\n out.teacherInstructions = null;\n out.config.rationale = null;\n out.config.teacherInstructions = null;\n }\n\n out.config.env = env;\n out.config.prompt = normalizedQuestion.promptEnabled\n ? normalizedQuestion.prompt\n : null;\n\n log('out: ', out);\n resolve(out);\n });\n });\n}\n\nconst escape = (string) => string.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&'); // $& means the whole matched string\n\nconst simpleSessionResponse = (question) =>\n new Promise((resolve) => {\n const { responses, id } = question;\n const { answer } = responses && responses.length ? responses[0] : {};\n\n resolve({\n id,\n response: answer || '',\n completeAnswer: answer || ''\n });\n });\n\nconst advancedSessionResponse = (question) =>\n new Promise((resolve, reject) => {\n const { responses, id } = question;\n const { answer } = responses && responses.length ? responses[0] : {};\n\n if (!answer) {\n resolve({\n id,\n answers: {},\n completeAnswer: ''\n });\n\n return;\n }\n\n try {\n const e = question.expression;\n const RESPONSE_TOKEN = /\\\\{\\\\{\\s*response\\s*\\\\}\\\\}/g;\n\n const o = escape(e).split(RESPONSE_TOKEN);\n const to = o.map((t) => (t === '' ? t : t.replace(/\\s+/g, () => '\\\\s*')));\n const tt = to.join('(.*)');\n\n const m = answer.match(new RegExp(tt));\n\n const count = o.length - 1;\n\n if (!m) {\n resolve({\n id,\n answers: {},\n completeAnswer: answer\n });\n\n console.log(`can not find match: ${o} in ${answer}`);\n\n return;\n }\n\n m.shift();\n\n const answers = {};\n\n for (var i = 0; i < count; i++) {\n answers[`r${i + 1}`] = { value: m[i].trim() };\n }\n\n resolve({\n id,\n answers,\n completeAnswer: answer\n });\n } catch (e) {\n resolve({\n id,\n answers: {},\n completeAnswer: answer\n });\n\n console.error(e.toString());\n }\n });\n\nexport const createCorrectResponseSession = (question, env) => {\n if (env.mode === 'evaluate' || env.role !== 'instructor') {\n // eslint-disable-next-line no-console\n console.error(\n 'can not create correct response session if mode is evaluate or role is not instructor'\n );\n\n return Promise.resolve(null);\n }\n\n if ((question.responseType || '').toLowerCase() === 'simple') {\n return simpleSessionResponse(question, env);\n } else {\n return advancedSessionResponse(question, env);\n }\n};\n\nexport const validate = (model = {}, config = {}) => {\n const { expression = '', responses, responseType } = model;\n const { maxResponseAreas } = config;\n const responsesErrors = {};\n\n (responses || []).forEach((response, index) => {\n const { answer } = response;\n const reversedAlternates = [ ...Object.entries(response.alternates || {}) ].reverse();\n const alternatesErrors = {};\n const responseError = {};\n\n if (answer === '') {\n responseError.answer = 'Content should not be empty.';\n }\n\n reversedAlternates.forEach(([key, value], index) => {\n if (value === '') {\n alternatesErrors[key] = 'Content should not be empty.';\n } else {\n const identicalAnswer = answer === value ||\n reversedAlternates.slice(index + 1).some(([ , val]) => val === value);\n\n if (identicalAnswer) {\n alternatesErrors[key] = 'Content should be unique.';\n }\n }\n });\n\n if (!isEmpty(responseError) || !isEmpty(alternatesErrors)) {\n responsesErrors[index] = { ...responseError, ...alternatesErrors };\n }\n });\n\n const errors = {};\n\n if (responseType === 'Advanced Multi') {\n const nbOfResponseAreas = (expression.match(/\\{\\{response\\}\\}/g) || []).length;\n\n if (nbOfResponseAreas > maxResponseAreas) {\n errors.responseAreasError = `No more than ${maxResponseAreas} response areas should be defined.`;\n } else if (nbOfResponseAreas < 1) {\n errors.responseAreasError = 'There should be at least 1 response area defined.';\n }\n }\n\n if (!isEmpty(responsesErrors)) {\n errors.responsesErrors = responsesErrors;\n }\n\n return errors;\n};\n"],"file":"index.js"}
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@pie-element/math-inline-controller",
3
3
  "private": true,
4
- "version": "5.4.1",
4
+ "version": "5.6.8",
5
5
  "description": "",
6
6
  "main": "lib/index.js",
7
7
  "module": "src/index.js",
@@ -9,9 +9,9 @@
9
9
  "test": "./node_modules/.bin/jest"
10
10
  },
11
11
  "dependencies": {
12
+ "@pie-framework/math-validation": "^1.2.2",
12
13
  "@pie-lib/controller-utils": "^0.2.26",
13
14
  "@pie-lib/feedback": "^0.4.27",
14
- "@pie-lib/math-evaluator": "2.1.6",
15
15
  "debug": "^3.1.0",
16
16
  "lodash": "^4.17.15"
17
17
  },