@pie-element/image-cloze-association 5.21.1-next.21 → 5.21.1-next.23
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/controller/lib/defaults.js +5 -1
- package/controller/lib/defaults.js.map +1 -1
- package/controller/lib/index.js +28 -26
- package/controller/lib/index.js.map +1 -1
- package/controller/lib/utils.js +1 -0
- package/controller/lib/utils.js.map +1 -1
- package/controller/src/defaults.js +5 -1
- package/controller/src/index.js +16 -17
- package/controller/src/utils.js +11 -4
- package/docs/demo/generate.js +1 -1
- package/lib/utils-correctness.js +1 -0
- package/lib/utils-correctness.js.map +1 -1
- package/package.json +2 -2
- package/src/utils-correctness.js +5 -1
|
@@ -4,6 +4,10 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports["default"] = void 0;
|
|
7
|
-
var _default = {
|
|
7
|
+
var _default = {
|
|
8
|
+
rationaleEnabled: true,
|
|
9
|
+
studentInstructionsEnabled: true,
|
|
10
|
+
teacherInstructionsEnabled: true
|
|
11
|
+
};
|
|
8
12
|
exports["default"] = _default;
|
|
9
13
|
//# sourceMappingURL=defaults.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/defaults.js"],"names":[],"mappings":";;;;;;eAAe,
|
|
1
|
+
{"version":3,"sources":["../src/defaults.js"],"names":["rationaleEnabled","studentInstructionsEnabled","teacherInstructionsEnabled"],"mappings":";;;;;;eAAe;AACbA,EAAAA,gBAAgB,EAAE,IADL;AAEbC,EAAAA,0BAA0B,EAAE,IAFf;AAGbC,EAAAA,0BAA0B,EAAE;AAHf,C","sourcesContent":["export default {\n rationaleEnabled: true,\n studentInstructionsEnabled: true,\n teacherInstructionsEnabled: true,\n};\n"],"file":"defaults.js"}
|
package/controller/lib/index.js
CHANGED
|
@@ -5,28 +5,22 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", {
|
|
6
6
|
value: true
|
|
7
7
|
});
|
|
8
|
-
exports.isResponseCorrect = exports.getPartialScore = exports.createCorrectResponseSession = void 0;
|
|
9
|
-
exports.model = model;
|
|
10
|
-
exports.normalize = void 0;
|
|
11
|
-
exports.outcome = outcome;
|
|
12
|
-
exports.validate = void 0;
|
|
8
|
+
exports.validate = exports.outcome = exports.normalize = exports.model = exports.isResponseCorrect = exports.getPartialScore = exports.createCorrectResponseSession = void 0;
|
|
13
9
|
|
|
14
10
|
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
15
11
|
|
|
16
12
|
var _debug = _interopRequireDefault(require("debug"));
|
|
17
13
|
|
|
18
|
-
var _isEmpty = _interopRequireDefault(require("lodash/isEmpty"));
|
|
19
|
-
|
|
20
|
-
var _shuffle = _interopRequireDefault(require("lodash/shuffle"));
|
|
21
|
-
|
|
22
14
|
var _humps = require("humps");
|
|
23
15
|
|
|
24
16
|
var _controllerUtils = require("@pie-lib/pie-toolbox/controller-utils");
|
|
25
17
|
|
|
26
|
-
var _utils = require("./utils");
|
|
27
|
-
|
|
28
18
|
var _lodash = require("lodash");
|
|
29
19
|
|
|
20
|
+
var _defaults = _interopRequireDefault(require("./defaults"));
|
|
21
|
+
|
|
22
|
+
var _utils = require("./utils");
|
|
23
|
+
|
|
30
24
|
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; }
|
|
31
25
|
|
|
32
26
|
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; }
|
|
@@ -34,16 +28,12 @@ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { va
|
|
|
34
28
|
var log = (0, _debug["default"])('pie-elements:image-cloze-association:controller');
|
|
35
29
|
|
|
36
30
|
var normalize = function normalize(question) {
|
|
37
|
-
return _objectSpread({
|
|
38
|
-
rationaleEnabled: true,
|
|
39
|
-
teacherInstructionsEnabled: true,
|
|
40
|
-
studentInstructionsEnabled: true
|
|
41
|
-
}, question);
|
|
31
|
+
return _objectSpread(_objectSpread({}, _defaults["default"]), question);
|
|
42
32
|
};
|
|
43
33
|
|
|
44
34
|
exports.normalize = normalize;
|
|
45
35
|
|
|
46
|
-
function model(question, session, env) {
|
|
36
|
+
var model = function model(question, session, env) {
|
|
47
37
|
var questionNormalized = normalize(question);
|
|
48
38
|
var questionCamelized = (0, _humps.camelizeKeys)(questionNormalized);
|
|
49
39
|
return new Promise(function (resolve) {
|
|
@@ -55,7 +45,7 @@ function model(question, session, env) {
|
|
|
55
45
|
});
|
|
56
46
|
|
|
57
47
|
if (questionNormalized.shuffle) {
|
|
58
|
-
out.possibleResponses = (0,
|
|
48
|
+
out.possibleResponses = (0, _lodash.shuffle)(questionNormalized.possible_responses);
|
|
59
49
|
}
|
|
60
50
|
|
|
61
51
|
if (env.role === 'instructor' && (env.mode === 'view' || env.mode === 'evaluate')) {
|
|
@@ -68,13 +58,16 @@ function model(question, session, env) {
|
|
|
68
58
|
|
|
69
59
|
resolve(out);
|
|
70
60
|
});
|
|
71
|
-
}
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
exports.model = model;
|
|
72
64
|
|
|
73
|
-
var isResponseCorrect = function isResponseCorrect(
|
|
65
|
+
var isResponseCorrect = function isResponseCorrect(correctResponses, session) {
|
|
66
|
+
var responses = (0, _lodash.cloneDeep)(correctResponses);
|
|
74
67
|
var isCorrect = true;
|
|
75
68
|
var totalValidResponses = 0;
|
|
76
69
|
|
|
77
|
-
if (!session || (0,
|
|
70
|
+
if (!session || (0, _lodash.isEmpty)(session)) {
|
|
78
71
|
return false;
|
|
79
72
|
}
|
|
80
73
|
|
|
@@ -84,7 +77,14 @@ var isResponseCorrect = function isResponseCorrect(responses, session) {
|
|
|
84
77
|
|
|
85
78
|
if (session.answers && totalValidResponses === session.answers.length) {
|
|
86
79
|
session.answers.forEach(function (answer) {
|
|
87
|
-
|
|
80
|
+
var _responses$answer$con;
|
|
81
|
+
|
|
82
|
+
var index = (((_responses$answer$con = responses[answer.containerIndex]) === null || _responses$answer$con === void 0 ? void 0 : _responses$answer$con.images) || []).indexOf(answer.value);
|
|
83
|
+
|
|
84
|
+
if (index >= 0) {
|
|
85
|
+
// remove response from correct responses array to ensure that duplicates are evaluated correctly
|
|
86
|
+
responses[answer.containerIndex].images.splice(index, 1);
|
|
87
|
+
} else {
|
|
88
88
|
isCorrect = false;
|
|
89
89
|
}
|
|
90
90
|
});
|
|
@@ -147,7 +147,7 @@ var getPartialScore = function getPartialScore(question, session) {
|
|
|
147
147
|
var incorrectAnswers = 0;
|
|
148
148
|
var possibleResponses = 0;
|
|
149
149
|
|
|
150
|
-
if (!session || (0,
|
|
150
|
+
if (!session || (0, _lodash.isEmpty)(session)) {
|
|
151
151
|
return 0;
|
|
152
152
|
}
|
|
153
153
|
|
|
@@ -205,12 +205,12 @@ var getScore = function getScore(config, session) {
|
|
|
205
205
|
return isPartialScoring ? getPartialScore(config, session) : correct ? 1 : 0;
|
|
206
206
|
};
|
|
207
207
|
|
|
208
|
-
function outcome(config, session) {
|
|
208
|
+
var outcome = function outcome(config, session) {
|
|
209
209
|
var env = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|
210
210
|
return new Promise(function (resolve) {
|
|
211
211
|
log('outcome...');
|
|
212
212
|
|
|
213
|
-
if (!session || (0,
|
|
213
|
+
if (!session || (0, _lodash.isEmpty)(session)) {
|
|
214
214
|
resolve({
|
|
215
215
|
score: 0,
|
|
216
216
|
empty: true
|
|
@@ -226,7 +226,9 @@ function outcome(config, session) {
|
|
|
226
226
|
});
|
|
227
227
|
}
|
|
228
228
|
});
|
|
229
|
-
}
|
|
229
|
+
};
|
|
230
|
+
|
|
231
|
+
exports.outcome = outcome;
|
|
230
232
|
|
|
231
233
|
var createCorrectResponseSession = function createCorrectResponseSession(question, env) {
|
|
232
234
|
return new Promise(function (resolve) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.js"],"names":["log","normalize","question","rationaleEnabled","teacherInstructionsEnabled","studentInstructionsEnabled","model","session","env","questionNormalized","questionCamelized","Promise","resolve","out","disabled","mode","responseCorrect","getScore","undefined","shuffle","possibleResponses","possible_responses","role","teacherInstructions","rationale","isResponseCorrect","responses","isCorrect","totalValidResponses","forEach","value","images","length","answers","answer","containerIndex","includes","keepNonEmptyResponses","filtered","filter","response","isDefaultOrAltResponseCorrect","altResponses","validation","validResponse","altResponse","getDeductionPerContainer","valid","totalStack","item","incorrectStack","maxValid","ignored","slice","getPartialScore","maxResponsePerZone","correctAnswers","incorrectAnswers","all","deductionList","id","nonEmptyResponses","denominator","str","toFixed","parseFloat","config","isPartialScoring","partialScoring","enabled","correct","outcome","score","empty","configCamelized","createCorrectResponseSession","valid_response","container","i","v","push","getInnerText","html","replaceAll","getContent","replace","validate","errors","field","required"],"mappings":"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","sourcesContent":["import debug from 'debug';\nimport isEmpty from 'lodash/isEmpty';\nimport shuffle from 'lodash/shuffle';\nimport { camelizeKeys } from 'humps';\nimport { partialScoring } from '@pie-lib/pie-toolbox/controller-utils';\n\nimport { getAllUniqueCorrectness } from './utils';\nimport { cloneDeep } from 'lodash';\n\nconst log = debug('pie-elements:image-cloze-association:controller');\n\nexport const normalize = (question) => ({\n rationaleEnabled: true,\n teacherInstructionsEnabled: true,\n studentInstructionsEnabled: true,\n ...question,\n});\n\nexport function model(question, session, env) {\n const questionNormalized = normalize(question);\n const questionCamelized = camelizeKeys(questionNormalized);\n\n return new Promise((resolve) => {\n const out = {\n disabled: env.mode !== 'gather',\n mode: env.mode,\n ...questionCamelized,\n responseCorrect: env.mode === 'evaluate' ? getScore(questionCamelized, session) === 1 : undefined,\n };\n\n if (questionNormalized.shuffle) {\n out.possibleResponses = shuffle(questionNormalized.possible_responses);\n }\n\n if (env.role === 'instructor' && (env.mode === 'view' || env.mode === 'evaluate')) {\n out.teacherInstructions = questionCamelized.teacherInstructionsEnabled\n ? questionCamelized.teacherInstructions\n : null;\n out.rationale = questionCamelized.rationale ? questionCamelized.rationale : null;\n } else {\n out.teacherInstructions = null;\n out.rationale = null;\n }\n\n resolve(out);\n });\n}\n\nexport const isResponseCorrect = (responses, session) => {\n let isCorrect = true;\n let totalValidResponses = 0;\n\n if (!session || isEmpty(session)) {\n return false;\n }\n\n responses.forEach((value) => (totalValidResponses += (value.images || []).length));\n\n if (session.answers && totalValidResponses === session.answers.length) {\n session.answers.forEach((answer) => {\n if (\n !((responses[answer.containerIndex] && responses[answer.containerIndex].images) || []).includes(answer.value)\n ) {\n isCorrect = false;\n }\n });\n } else {\n isCorrect = false;\n }\n return isCorrect;\n};\n\n// This applies for correct responses that have empty values\nconst keepNonEmptyResponses = (responses) => {\n const filtered = responses.filter((response) => response.images && response.images.length);\n return cloneDeep(filtered);\n};\n\n// This applies for items that don't support partial scoring.\nconst isDefaultOrAltResponseCorrect = (question, session) => {\n const {\n validation: { altResponses },\n } = question;\n let {\n validation: {\n validResponse: { value },\n },\n } = question;\n\n let isCorrect = isResponseCorrect(value, session);\n\n // Look for correct answers in alternate responses.\n if (!isCorrect && altResponses && altResponses.length) {\n altResponses.forEach((altResponse) => {\n if (isResponseCorrect(altResponse.value, session)) {\n isCorrect = true;\n }\n });\n }\n return isCorrect;\n};\n\n// Deduct only the items that exceeded the maximum valid response per container.\nconst getDeductionPerContainer = (containerIndex, answers, valid) => {\n const totalStack = answers.filter((item) => item.containerIndex === containerIndex);\n const incorrectStack = totalStack.filter((item) => !item.isCorrect);\n const maxValid = (valid.value[containerIndex].images || []).length;\n\n if (totalStack.length > maxValid) {\n const ignored = totalStack.length - maxValid;\n return incorrectStack.slice(-ignored);\n }\n return [];\n};\n\nexport const getPartialScore = (question, session) => {\n const {\n validation: { validResponse },\n maxResponsePerZone,\n } = question;\n let correctAnswers = 0;\n let incorrectAnswers = 0;\n let possibleResponses = 0;\n\n if (!session || isEmpty(session)) {\n return 0;\n }\n\n validResponse.value.forEach((value) => (possibleResponses += (value.images || []).length));\n\n if (session.answers && session.answers.length) {\n const all = getAllUniqueCorrectness(session.answers, validResponse.value);\n correctAnswers = all.filter((item) => item.isCorrect).length;\n incorrectAnswers = all.filter((item) => !item.isCorrect).length;\n\n // deduction rules: https://docs.google.com/document/d/1Oprm8Qs5fg_Dwoj2pNpsfu4D63QgCZgvcqTgeaVel7I/edit\n session.answers.forEach((answer) => {\n if (maxResponsePerZone > 1) {\n const deductionList = getDeductionPerContainer(answer.containerIndex, all, validResponse);\n\n if (deductionList.length) {\n deductionList.forEach((item) => {\n if (item.id === answer.id) {\n correctAnswers -= 1;\n }\n });\n }\n }\n });\n\n if (!maxResponsePerZone || maxResponsePerZone <= 1) {\n correctAnswers -= incorrectAnswers;\n }\n } else {\n correctAnswers = 0;\n }\n // negative values will implicitly make the score equal to zero\n correctAnswers = correctAnswers < 0 ? 0 : correctAnswers;\n\n // use length of validResponse since some containers can be left empty\n const nonEmptyResponses = keepNonEmptyResponses(validResponse.value);\n const denominator = maxResponsePerZone > 1 ? possibleResponses : (nonEmptyResponses || []).length;\n const str = (correctAnswers / denominator).toFixed(2);\n\n return parseFloat(str);\n};\n\nconst getScore = (config, session, env = {}) => {\n const isPartialScoring = partialScoring.enabled(config, env);\n const correct = isDefaultOrAltResponseCorrect(config, session);\n\n return isPartialScoring ? getPartialScore(config, session) : correct ? 1 : 0;\n};\n\nexport function outcome(config, session, env = {}) {\n return new Promise((resolve) => {\n log('outcome...');\n if (!session || isEmpty(session)) {\n resolve({ score: 0, empty: true });\n }\n\n const configCamelized = camelizeKeys(config);\n\n if (session.answers || []) {\n const score = getScore(configCamelized, session, env);\n resolve({ score });\n }\n });\n}\n\nexport const createCorrectResponseSession = (question, env) => {\n return new Promise((resolve) => {\n if (env.mode !== 'evaluate' && env.role === 'instructor') {\n const {\n validation: {\n valid_response: { value },\n },\n } = question;\n const answers = [];\n\n if (value) {\n value.forEach((container, i) => {\n (container.images || []).forEach((v) => {\n answers.push({\n value: v,\n containerIndex: i,\n });\n });\n });\n }\n\n resolve({\n answers,\n id: '1',\n });\n } else {\n 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 and iframe\nconst getContent = (html) => (html || '').replace(/(<(?!img|iframe)([^>]+)>)/gi, '');\n\nexport const validate = (model = {}, config = {}) => {\n const errors = {};\n\n ['teacherInstructions'].forEach((field) => {\n if (config[field]?.required && !getContent(model[field])) {\n errors[field] = 'This field is required.';\n }\n });\n\n return errors;\n};\n"],"file":"index.js"}
|
|
1
|
+
{"version":3,"sources":["../src/index.js"],"names":["log","normalize","question","defaults","model","session","env","questionNormalized","questionCamelized","Promise","resolve","out","disabled","mode","responseCorrect","getScore","undefined","shuffle","possibleResponses","possible_responses","role","teacherInstructions","teacherInstructionsEnabled","rationale","isResponseCorrect","correctResponses","responses","isCorrect","totalValidResponses","forEach","value","images","length","answers","answer","index","containerIndex","indexOf","splice","keepNonEmptyResponses","filtered","filter","response","isDefaultOrAltResponseCorrect","altResponses","validation","validResponse","altResponse","getDeductionPerContainer","valid","totalStack","item","incorrectStack","maxValid","ignored","slice","getPartialScore","maxResponsePerZone","correctAnswers","incorrectAnswers","all","deductionList","id","nonEmptyResponses","denominator","str","toFixed","parseFloat","config","isPartialScoring","partialScoring","enabled","correct","outcome","score","empty","configCamelized","createCorrectResponseSession","valid_response","container","i","v","push","getInnerText","html","replaceAll","getContent","replace","validate","errors","field","required"],"mappings":";;;;;;;;;;;AAAA;;AACA;;AACA;;AACA;;AAEA;;AACA;;;;;;AAEA,IAAMA,GAAG,GAAG,uBAAM,iDAAN,CAAZ;;AAEO,IAAMC,SAAS,GAAG,SAAZA,SAAY,CAACC,QAAD;AAAA,yCAAoBC,oBAApB,GAAiCD,QAAjC;AAAA,CAAlB;;;;AAEA,IAAME,KAAK,GAAG,SAARA,KAAQ,CAACF,QAAD,EAAWG,OAAX,EAAoBC,GAApB,EAA4B;AAC/C,MAAMC,kBAAkB,GAAGN,SAAS,CAACC,QAAD,CAApC;AACA,MAAMM,iBAAiB,GAAG,yBAAaD,kBAAb,CAA1B;AAEA,SAAO,IAAIE,OAAJ,CAAY,UAACC,OAAD,EAAa;AAC9B,QAAMC,GAAG;AACPC,MAAAA,QAAQ,EAAEN,GAAG,CAACO,IAAJ,KAAa,QADhB;AAEPA,MAAAA,IAAI,EAAEP,GAAG,CAACO;AAFH,OAGJL,iBAHI;AAIPM,MAAAA,eAAe,EAAER,GAAG,CAACO,IAAJ,KAAa,UAAb,GAA0BE,QAAQ,CAACP,iBAAD,EAAoBH,OAApB,CAAR,KAAyC,CAAnE,GAAuEW;AAJjF,MAAT;;AAOA,QAAIT,kBAAkB,CAACU,OAAvB,EAAgC;AAC9BN,MAAAA,GAAG,CAACO,iBAAJ,GAAwB,qBAAQX,kBAAkB,CAACY,kBAA3B,CAAxB;AACD;;AAED,QAAIb,GAAG,CAACc,IAAJ,KAAa,YAAb,KAA8Bd,GAAG,CAACO,IAAJ,KAAa,MAAb,IAAuBP,GAAG,CAACO,IAAJ,KAAa,UAAlE,CAAJ,EAAmF;AACjFF,MAAAA,GAAG,CAACU,mBAAJ,GAA0Bb,iBAAiB,CAACc,0BAAlB,GACtBd,iBAAiB,CAACa,mBADI,GAEtB,IAFJ;AAGAV,MAAAA,GAAG,CAACY,SAAJ,GAAgBf,iBAAiB,CAACe,SAAlB,GAA8Bf,iBAAiB,CAACe,SAAhD,GAA4D,IAA5E;AACD,KALD,MAKO;AACLZ,MAAAA,GAAG,CAACU,mBAAJ,GAA0B,IAA1B;AACAV,MAAAA,GAAG,CAACY,SAAJ,GAAgB,IAAhB;AACD;;AAEDb,IAAAA,OAAO,CAACC,GAAD,CAAP;AACD,GAvBM,CAAP;AAwBD,CA5BM;;;;AA8BA,IAAMa,iBAAiB,GAAG,SAApBA,iBAAoB,CAACC,gBAAD,EAAmBpB,OAAnB,EAA+B;AAC9D,MAAMqB,SAAS,GAAG,uBAAUD,gBAAV,CAAlB;AACA,MAAIE,SAAS,GAAG,IAAhB;AACA,MAAIC,mBAAmB,GAAG,CAA1B;;AAEA,MAAI,CAACvB,OAAD,IAAY,qBAAQA,OAAR,CAAhB,EAAkC;AAChC,WAAO,KAAP;AACD;;AAEDqB,EAAAA,SAAS,CAACG,OAAV,CAAkB,UAACC,KAAD;AAAA,WAAYF,mBAAmB,IAAI,CAACE,KAAK,CAACC,MAAN,IAAgB,EAAjB,EAAqBC,MAAxD;AAAA,GAAlB;;AAEA,MAAI3B,OAAO,CAAC4B,OAAR,IAAmBL,mBAAmB,KAAKvB,OAAO,CAAC4B,OAAR,CAAgBD,MAA/D,EAAuE;AACrE3B,IAAAA,OAAO,CAAC4B,OAAR,CAAgBJ,OAAhB,CAAwB,UAACK,MAAD,EAAY;AAAA;;AAClC,UAAMC,KAAK,GAAG,CAAC,0BAAAT,SAAS,CAACQ,MAAM,CAACE,cAAR,CAAT,gFAAkCL,MAAlC,KAA4C,EAA7C,EAAiDM,OAAjD,CAAyDH,MAAM,CAACJ,KAAhE,CAAd;;AAEA,UAAIK,KAAK,IAAI,CAAb,EAAgB;AACd;AACAT,QAAAA,SAAS,CAACQ,MAAM,CAACE,cAAR,CAAT,CAAiCL,MAAjC,CAAwCO,MAAxC,CAA+CH,KAA/C,EAAsD,CAAtD;AACD,OAHD,MAGO;AACLR,QAAAA,SAAS,GAAG,KAAZ;AACD;AACF,KATD;AAUD,GAXD,MAWO;AACLA,IAAAA,SAAS,GAAG,KAAZ;AACD;;AAED,SAAOA,SAAP;AACD,CA3BM,C,CA6BP;;;;;AACA,IAAMY,qBAAqB,GAAG,SAAxBA,qBAAwB,CAACb,SAAD,EAAe;AAC3C,MAAMc,QAAQ,GAAGd,SAAS,CAACe,MAAV,CAAiB,UAACC,QAAD;AAAA,WAAcA,QAAQ,CAACX,MAAT,IAAmBW,QAAQ,CAACX,MAAT,CAAgBC,MAAjD;AAAA,GAAjB,CAAjB;AACA,SAAO,uBAAUQ,QAAV,CAAP;AACD,CAHD,C,CAKA;;;AACA,IAAMG,6BAA6B,GAAG,SAAhCA,6BAAgC,CAACzC,QAAD,EAAWG,OAAX,EAAuB;AAC3D,MACgBuC,YADhB,GAEI1C,QAFJ,CACE2C,UADF,CACgBD,YADhB;AAGA,MAEqBd,KAFrB,GAII5B,QAJJ,CACE2C,UADF,CAEIC,aAFJ,CAEqBhB,KAFrB;AAMA,MAAIH,SAAS,GAAGH,iBAAiB,CAACM,KAAD,EAAQzB,OAAR,CAAjC,CAV2D,CAY3D;;AACA,MAAI,CAACsB,SAAD,IAAciB,YAAd,IAA8BA,YAAY,CAACZ,MAA/C,EAAuD;AACrDY,IAAAA,YAAY,CAACf,OAAb,CAAqB,UAACkB,WAAD,EAAiB;AACpC,UAAIvB,iBAAiB,CAACuB,WAAW,CAACjB,KAAb,EAAoBzB,OAApB,CAArB,EAAmD;AACjDsB,QAAAA,SAAS,GAAG,IAAZ;AACD;AACF,KAJD;AAKD;;AACD,SAAOA,SAAP;AACD,CArBD,C,CAuBA;;;AACA,IAAMqB,wBAAwB,GAAG,SAA3BA,wBAA2B,CAACZ,cAAD,EAAiBH,OAAjB,EAA0BgB,KAA1B,EAAoC;AACnE,MAAMC,UAAU,GAAGjB,OAAO,CAACQ,MAAR,CAAe,UAACU,IAAD;AAAA,WAAUA,IAAI,CAACf,cAAL,KAAwBA,cAAlC;AAAA,GAAf,CAAnB;AACA,MAAMgB,cAAc,GAAGF,UAAU,CAACT,MAAX,CAAkB,UAACU,IAAD;AAAA,WAAU,CAACA,IAAI,CAACxB,SAAhB;AAAA,GAAlB,CAAvB;AACA,MAAM0B,QAAQ,GAAG,CAACJ,KAAK,CAACnB,KAAN,CAAYM,cAAZ,EAA4BL,MAA5B,IAAsC,EAAvC,EAA2CC,MAA5D;;AAEA,MAAIkB,UAAU,CAAClB,MAAX,GAAoBqB,QAAxB,EAAkC;AAChC,QAAMC,OAAO,GAAGJ,UAAU,CAAClB,MAAX,GAAoBqB,QAApC;AACA,WAAOD,cAAc,CAACG,KAAf,CAAqB,CAACD,OAAtB,CAAP;AACD;;AACD,SAAO,EAAP;AACD,CAVD;;AAYO,IAAME,eAAe,GAAG,SAAlBA,eAAkB,CAACtD,QAAD,EAAWG,OAAX,EAAuB;AACpD,MACgByC,aADhB,GAGI5C,QAHJ,CACE2C,UADF,CACgBC,aADhB;AAAA,MAEEW,kBAFF,GAGIvD,QAHJ,CAEEuD,kBAFF;AAIA,MAAIC,cAAc,GAAG,CAArB;AACA,MAAIC,gBAAgB,GAAG,CAAvB;AACA,MAAIzC,iBAAiB,GAAG,CAAxB;;AAEA,MAAI,CAACb,OAAD,IAAY,qBAAQA,OAAR,CAAhB,EAAkC;AAChC,WAAO,CAAP;AACD;;AAEDyC,EAAAA,aAAa,CAAChB,KAAd,CAAoBD,OAApB,CAA4B,UAACC,KAAD;AAAA,WAAYZ,iBAAiB,IAAI,CAACY,KAAK,CAACC,MAAN,IAAgB,EAAjB,EAAqBC,MAAtD;AAAA,GAA5B;;AAEA,MAAI3B,OAAO,CAAC4B,OAAR,IAAmB5B,OAAO,CAAC4B,OAAR,CAAgBD,MAAvC,EAA+C;AAC7C,QAAM4B,GAAG,GAAG,oCAAwBvD,OAAO,CAAC4B,OAAhC,EAAyCa,aAAa,CAAChB,KAAvD,CAAZ;AACA4B,IAAAA,cAAc,GAAGE,GAAG,CAACnB,MAAJ,CAAW,UAACU,IAAD;AAAA,aAAUA,IAAI,CAACxB,SAAf;AAAA,KAAX,EAAqCK,MAAtD;AACA2B,IAAAA,gBAAgB,GAAGC,GAAG,CAACnB,MAAJ,CAAW,UAACU,IAAD;AAAA,aAAU,CAACA,IAAI,CAACxB,SAAhB;AAAA,KAAX,EAAsCK,MAAzD,CAH6C,CAK7C;;AACA3B,IAAAA,OAAO,CAAC4B,OAAR,CAAgBJ,OAAhB,CAAwB,UAACK,MAAD,EAAY;AAClC,UAAIuB,kBAAkB,GAAG,CAAzB,EAA4B;AAC1B,YAAMI,aAAa,GAAGb,wBAAwB,CAACd,MAAM,CAACE,cAAR,EAAwBwB,GAAxB,EAA6Bd,aAA7B,CAA9C;;AAEA,YAAIe,aAAa,CAAC7B,MAAlB,EAA0B;AACxB6B,UAAAA,aAAa,CAAChC,OAAd,CAAsB,UAACsB,IAAD,EAAU;AAC9B,gBAAIA,IAAI,CAACW,EAAL,KAAY5B,MAAM,CAAC4B,EAAvB,EAA2B;AACzBJ,cAAAA,cAAc,IAAI,CAAlB;AACD;AACF,WAJD;AAKD;AACF;AACF,KAZD;;AAcA,QAAI,CAACD,kBAAD,IAAuBA,kBAAkB,IAAI,CAAjD,EAAoD;AAClDC,MAAAA,cAAc,IAAIC,gBAAlB;AACD;AACF,GAvBD,MAuBO;AACLD,IAAAA,cAAc,GAAG,CAAjB;AACD,GAxCmD,CAyCpD;;;AACAA,EAAAA,cAAc,GAAGA,cAAc,GAAG,CAAjB,GAAqB,CAArB,GAAyBA,cAA1C,CA1CoD,CA4CpD;;AACA,MAAMK,iBAAiB,GAAGxB,qBAAqB,CAACO,aAAa,CAAChB,KAAf,CAA/C;AACA,MAAMkC,WAAW,GAAGP,kBAAkB,GAAG,CAArB,GAAyBvC,iBAAzB,GAA6C,CAAC6C,iBAAiB,IAAI,EAAtB,EAA0B/B,MAA3F;AACA,MAAMiC,GAAG,GAAG,CAACP,cAAc,GAAGM,WAAlB,EAA+BE,OAA/B,CAAuC,CAAvC,CAAZ;AAEA,SAAOC,UAAU,CAACF,GAAD,CAAjB;AACD,CAlDM;;;;AAoDP,IAAMlD,QAAQ,GAAG,SAAXA,QAAW,CAACqD,MAAD,EAAS/D,OAAT,EAA+B;AAAA,MAAbC,GAAa,uEAAP,EAAO;;AAC9C,MAAM+D,gBAAgB,GAAGC,gCAAeC,OAAf,CAAuBH,MAAvB,EAA+B9D,GAA/B,CAAzB;;AACA,MAAMkE,OAAO,GAAG7B,6BAA6B,CAACyB,MAAD,EAAS/D,OAAT,CAA7C;AAEA,SAAOgE,gBAAgB,GAAGb,eAAe,CAACY,MAAD,EAAS/D,OAAT,CAAlB,GAAsCmE,OAAO,GAAG,CAAH,GAAO,CAA3E;AACD,CALD;;AAOO,IAAMC,OAAO,GAAG,SAAVA,OAAU,CAACL,MAAD,EAAS/D,OAAT,EAA+B;AAAA,MAAbC,GAAa,uEAAP,EAAO;AACpD,SAAO,IAAIG,OAAJ,CAAY,UAACC,OAAD,EAAa;AAC9BV,IAAAA,GAAG,CAAC,YAAD,CAAH;;AACA,QAAI,CAACK,OAAD,IAAY,qBAAQA,OAAR,CAAhB,EAAkC;AAChCK,MAAAA,OAAO,CAAC;AAAEgE,QAAAA,KAAK,EAAE,CAAT;AAAYC,QAAAA,KAAK,EAAE;AAAnB,OAAD,CAAP;AACD;;AAED,QAAMC,eAAe,GAAG,yBAAaR,MAAb,CAAxB;;AAEA,QAAI/D,OAAO,CAAC4B,OAAR,IAAmB,EAAvB,EAA2B;AACzB,UAAMyC,KAAK,GAAG3D,QAAQ,CAAC6D,eAAD,EAAkBvE,OAAlB,EAA2BC,GAA3B,CAAtB;AACAI,MAAAA,OAAO,CAAC;AAAEgE,QAAAA,KAAK,EAALA;AAAF,OAAD,CAAP;AACD;AACF,GAZM,CAAP;AAaD,CAdM;;;;AAgBA,IAAMG,4BAA4B,GAAG,SAA/BA,4BAA+B,CAAC3E,QAAD,EAAWI,GAAX,EAAmB;AAC7D,SAAO,IAAIG,OAAJ,CAAY,UAACC,OAAD,EAAa;AAC9B,QAAIJ,GAAG,CAACO,IAAJ,KAAa,UAAb,IAA2BP,GAAG,CAACc,IAAJ,KAAa,YAA5C,EAA0D;AACxD,UAEsBU,KAFtB,GAII5B,QAJJ,CACE2C,UADF,CAEIiC,cAFJ,CAEsBhD,KAFtB;AAKA,UAAMG,OAAO,GAAG,EAAhB;;AAEA,UAAIH,KAAJ,EAAW;AACTA,QAAAA,KAAK,CAACD,OAAN,CAAc,UAACkD,SAAD,EAAYC,CAAZ,EAAkB;AAC9B,WAACD,SAAS,CAAChD,MAAV,IAAoB,EAArB,EAAyBF,OAAzB,CAAiC,UAACoD,CAAD,EAAO;AACtChD,YAAAA,OAAO,CAACiD,IAAR,CAAa;AACXpD,cAAAA,KAAK,EAAEmD,CADI;AAEX7C,cAAAA,cAAc,EAAE4C;AAFL,aAAb;AAID,WALD;AAMD,SAPD;AAQD;;AAEDtE,MAAAA,OAAO,CAAC;AACNuB,QAAAA,OAAO,EAAPA,OADM;AAEN6B,QAAAA,EAAE,EAAE;AAFE,OAAD,CAAP;AAID,KAvBD,MAuBO;AACLpD,MAAAA,OAAO,CAAC,IAAD,CAAP;AACD;AACF,GA3BM,CAAP;AA4BD,CA7BM,C,CA+BP;;;;;AACA,IAAMyE,YAAY,GAAG,SAAfA,YAAe,CAACC,IAAD;AAAA,SAAU,CAACA,IAAI,IAAI,EAAT,EAAaC,UAAb,CAAwB,UAAxB,EAAoC,EAApC,CAAV;AAAA,CAArB,C,CAEA;;;AACA,IAAMC,UAAU,GAAG,SAAbA,UAAa,CAACF,IAAD;AAAA,SAAU,CAACA,IAAI,IAAI,EAAT,EAAaG,OAAb,CAAqB,6BAArB,EAAoD,EAApD,CAAV;AAAA,CAAnB;;AAEO,IAAMC,QAAQ,GAAG,SAAXA,QAAW,GAA6B;AAAA,MAA5BpF,KAA4B,uEAApB,EAAoB;AAAA,MAAhBgE,MAAgB,uEAAP,EAAO;AACnD,MAAMqB,MAAM,GAAG,EAAf;AAEA,GAAC,qBAAD,EAAwB5D,OAAxB,CAAgC,UAAC6D,KAAD,EAAW;AAAA;;AACzC,QAAI,iBAAAtB,MAAM,CAACsB,KAAD,CAAN,wDAAeC,QAAf,IAA2B,CAACL,UAAU,CAAClF,KAAK,CAACsF,KAAD,CAAN,CAA1C,EAA0D;AACxDD,MAAAA,MAAM,CAACC,KAAD,CAAN,GAAgB,yBAAhB;AACD;AACF,GAJD;AAMA,SAAOD,MAAP;AACD,CAVM","sourcesContent":["import debug from 'debug';\nimport { camelizeKeys } from 'humps';\nimport { partialScoring } from '@pie-lib/pie-toolbox/controller-utils';\nimport { cloneDeep, isEmpty, shuffle } from 'lodash';\n\nimport defaults from './defaults';\nimport { getAllUniqueCorrectness } from './utils';\n\nconst log = debug('pie-elements:image-cloze-association:controller');\n\nexport const normalize = (question) => ({ ...defaults, ...question });\n\nexport const model = (question, session, env) => {\n const questionNormalized = normalize(question);\n const questionCamelized = camelizeKeys(questionNormalized);\n\n return new Promise((resolve) => {\n const out = {\n disabled: env.mode !== 'gather',\n mode: env.mode,\n ...questionCamelized,\n responseCorrect: env.mode === 'evaluate' ? getScore(questionCamelized, session) === 1 : undefined,\n };\n\n if (questionNormalized.shuffle) {\n out.possibleResponses = shuffle(questionNormalized.possible_responses);\n }\n\n if (env.role === 'instructor' && (env.mode === 'view' || env.mode === 'evaluate')) {\n out.teacherInstructions = questionCamelized.teacherInstructionsEnabled\n ? questionCamelized.teacherInstructions\n : null;\n out.rationale = questionCamelized.rationale ? questionCamelized.rationale : null;\n } else {\n out.teacherInstructions = null;\n out.rationale = null;\n }\n\n resolve(out);\n });\n};\n\nexport const isResponseCorrect = (correctResponses, session) => {\n const responses = cloneDeep(correctResponses);\n let isCorrect = true;\n let totalValidResponses = 0;\n\n if (!session || isEmpty(session)) {\n return false;\n }\n\n responses.forEach((value) => (totalValidResponses += (value.images || []).length));\n\n if (session.answers && totalValidResponses === session.answers.length) {\n session.answers.forEach((answer) => {\n const index = (responses[answer.containerIndex]?.images || []).indexOf(answer.value);\n\n if (index >= 0) {\n // remove response from correct responses array to ensure that duplicates are evaluated correctly\n responses[answer.containerIndex].images.splice(index, 1);\n } else {\n isCorrect = false;\n }\n });\n } else {\n isCorrect = false;\n }\n\n return isCorrect;\n};\n\n// This applies for correct responses that have empty values\nconst keepNonEmptyResponses = (responses) => {\n const filtered = responses.filter((response) => response.images && response.images.length);\n return cloneDeep(filtered);\n};\n\n// This applies for items that don't support partial scoring.\nconst isDefaultOrAltResponseCorrect = (question, session) => {\n const {\n validation: { altResponses },\n } = question;\n let {\n validation: {\n validResponse: { value },\n },\n } = question;\n\n let isCorrect = isResponseCorrect(value, session);\n\n // Look for correct answers in alternate responses.\n if (!isCorrect && altResponses && altResponses.length) {\n altResponses.forEach((altResponse) => {\n if (isResponseCorrect(altResponse.value, session)) {\n isCorrect = true;\n }\n });\n }\n return isCorrect;\n};\n\n// Deduct only the items that exceeded the maximum valid response per container.\nconst getDeductionPerContainer = (containerIndex, answers, valid) => {\n const totalStack = answers.filter((item) => item.containerIndex === containerIndex);\n const incorrectStack = totalStack.filter((item) => !item.isCorrect);\n const maxValid = (valid.value[containerIndex].images || []).length;\n\n if (totalStack.length > maxValid) {\n const ignored = totalStack.length - maxValid;\n return incorrectStack.slice(-ignored);\n }\n return [];\n};\n\nexport const getPartialScore = (question, session) => {\n const {\n validation: { validResponse },\n maxResponsePerZone,\n } = question;\n let correctAnswers = 0;\n let incorrectAnswers = 0;\n let possibleResponses = 0;\n\n if (!session || isEmpty(session)) {\n return 0;\n }\n\n validResponse.value.forEach((value) => (possibleResponses += (value.images || []).length));\n\n if (session.answers && session.answers.length) {\n const all = getAllUniqueCorrectness(session.answers, validResponse.value);\n correctAnswers = all.filter((item) => item.isCorrect).length;\n incorrectAnswers = all.filter((item) => !item.isCorrect).length;\n\n // deduction rules: https://docs.google.com/document/d/1Oprm8Qs5fg_Dwoj2pNpsfu4D63QgCZgvcqTgeaVel7I/edit\n session.answers.forEach((answer) => {\n if (maxResponsePerZone > 1) {\n const deductionList = getDeductionPerContainer(answer.containerIndex, all, validResponse);\n\n if (deductionList.length) {\n deductionList.forEach((item) => {\n if (item.id === answer.id) {\n correctAnswers -= 1;\n }\n });\n }\n }\n });\n\n if (!maxResponsePerZone || maxResponsePerZone <= 1) {\n correctAnswers -= incorrectAnswers;\n }\n } else {\n correctAnswers = 0;\n }\n // negative values will implicitly make the score equal to zero\n correctAnswers = correctAnswers < 0 ? 0 : correctAnswers;\n\n // use length of validResponse since some containers can be left empty\n const nonEmptyResponses = keepNonEmptyResponses(validResponse.value);\n const denominator = maxResponsePerZone > 1 ? possibleResponses : (nonEmptyResponses || []).length;\n const str = (correctAnswers / denominator).toFixed(2);\n\n return parseFloat(str);\n};\n\nconst getScore = (config, session, env = {}) => {\n const isPartialScoring = partialScoring.enabled(config, env);\n const correct = isDefaultOrAltResponseCorrect(config, session);\n\n return isPartialScoring ? getPartialScore(config, session) : correct ? 1 : 0;\n};\n\nexport const outcome = (config, session, env = {}) => {\n return new Promise((resolve) => {\n log('outcome...');\n if (!session || isEmpty(session)) {\n resolve({ score: 0, empty: true });\n }\n\n const configCamelized = camelizeKeys(config);\n\n if (session.answers || []) {\n const score = getScore(configCamelized, session, env);\n resolve({ score });\n }\n });\n};\n\nexport const createCorrectResponseSession = (question, env) => {\n return new Promise((resolve) => {\n if (env.mode !== 'evaluate' && env.role === 'instructor') {\n const {\n validation: {\n valid_response: { value },\n },\n } = question;\n const answers = [];\n\n if (value) {\n value.forEach((container, i) => {\n (container.images || []).forEach((v) => {\n answers.push({\n value: v,\n containerIndex: i,\n });\n });\n });\n }\n\n resolve({\n answers,\n id: '1',\n });\n } else {\n 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 and iframe\nconst getContent = (html) => (html || '').replace(/(<(?!img|iframe)([^>]+)>)/gi, '');\n\nexport const validate = (model = {}, config = {}) => {\n const errors = {};\n\n ['teacherInstructions'].forEach((field) => {\n if (config[field]?.required && !getContent(model[field])) {\n errors[field] = 'This field is required.';\n }\n });\n\n return errors;\n};\n"],"file":"index.js"}
|
package/controller/lib/utils.js
CHANGED
|
@@ -13,6 +13,7 @@ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (O
|
|
|
13
13
|
|
|
14
14
|
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; }
|
|
15
15
|
|
|
16
|
+
// functions also used in src/utils-correctness.js
|
|
16
17
|
var getAllCorrectness = function getAllCorrectness(answers, responses) {
|
|
17
18
|
return (answers || []).map(function (answer) {
|
|
18
19
|
return _objectSpread(_objectSpread({}, answer), {}, {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/utils.js"],"names":["getAllCorrectness","answers","responses","map","answer","isCorrect","containerIndex","images","includes","value","getValidAnswer","response","filter","res","getAllUniqueCorrectness","validResponses","allCorrectness","forEach","answer1","valuesToParse","answer2","length","shift","index","finalAnswer","id","valid"],"mappings":";;;;;;;;;;;;;;;AAAA,IAAMA,iBAAiB,GAAG,SAApBA,iBAAoB,CAACC,OAAD,EAAUC,SAAV;AAAA,
|
|
1
|
+
{"version":3,"sources":["../src/utils.js"],"names":["getAllCorrectness","answers","responses","map","answer","isCorrect","containerIndex","images","includes","value","getValidAnswer","response","filter","res","getAllUniqueCorrectness","validResponses","allCorrectness","forEach","answer1","valuesToParse","answer2","length","shift","index","finalAnswer","id","valid"],"mappings":";;;;;;;;;;;;;;;AAAA;AAEA,IAAMA,iBAAiB,GAAG,SAApBA,iBAAoB,CAACC,OAAD,EAAUC,SAAV;AAAA,SACxB,CAACD,OAAO,IAAI,EAAZ,EAAgBE,GAAhB,CAAoB,UAACC,MAAD;AAAA,2CACfA,MADe;AAElBC,MAAAA,SAAS,EAAE,CAAEH,SAAS,CAACE,MAAM,CAACE,cAAR,CAAT,IAAoCJ,SAAS,CAACE,MAAM,CAACE,cAAR,CAAT,CAAiCC,MAAtE,IAAiF,EAAlF,EAAsFC,QAAtF,CACTJ,MAAM,CAACK,KADE;AAFO;AAAA,GAApB,CADwB;AAAA,CAA1B;;AAQA,IAAMC,cAAc,GAAG,SAAjBA,cAAiB,CAACN,MAAD,EAASO,QAAT;AAAA,SACrB,CAAEA,QAAQ,CAACP,MAAM,CAACE,cAAR,CAAR,IAAmCK,QAAQ,CAACP,MAAM,CAACE,cAAR,CAAR,CAAgCC,MAApE,IAA+E,EAAhF,EAAoFK,MAApF,CACE,UAACC,GAAD;AAAA,WAASA,GAAG,KAAKT,MAAM,CAACK,KAAxB;AAAA,GADF,CADqB;AAAA,CAAvB;;AAKO,IAAMK,uBAAuB,GAAG,SAA1BA,uBAA0B,CAACb,OAAD,EAAUc,cAAV,EAA6B;AAClE,MAAIC,cAAc,GAAGhB,iBAAiB,CAACC,OAAD,EAAUc,cAAV,CAAtC;AAEAd,EAAAA,OAAO,CAACgB,OAAR,CAAgB,UAACC,OAAD,EAAa;AAC3B,QAAMC,aAAa,GAAGlB,OAAO,CAACW,MAAR,CACpB,UAACQ,OAAD;AAAA,aAAaA,OAAO,CAACX,KAAR,KAAkBS,OAAO,CAACT,KAA1B,IAAmCW,OAAO,CAACd,cAAR,KAA2BY,OAAO,CAACZ,cAAnF;AAAA,KADoB,CAAtB;;AAIA,QAAIa,aAAa,CAACE,MAAd,GAAuB,CAA3B,EAA8B;AAC5B;AACAF,MAAAA,aAAa,CAACG,KAAd,GAF4B,CAG5B;;AACAH,MAAAA,aAAa,CAACF,OAAd,CAAsB,UAACR,KAAD,EAAQc,KAAR,EAAkB;AACtCP,QAAAA,cAAc,GAAG,CAACA,cAAc,IAAI,EAAnB,EAAuBb,GAAvB,CAA2B,UAACqB,WAAD,EAAiB;AAC3D,cAAIA,WAAW,CAACC,EAAZ,KAAmBhB,KAAK,CAACgB,EAA7B,EAAiC;AAC/B,gBAAIC,KAAK,GAAGhB,cAAc,CAACc,WAAD,EAAcT,cAAd,CAA1B;AACA,mDACKS,WADL;AAEEnB,cAAAA,SAAS,EAAEqB,KAAK,CAACL,MAAN,GAAeE,KAAK,GAAG;AAFpC;AAID;;AACD,iBAAOC,WAAP;AACD,SATgB,CAAjB;AAUD,OAXD;AAYD;AACF,GAtBD;AAuBA,SAAOR,cAAP;AACD,CA3BM","sourcesContent":["// functions also used in src/utils-correctness.js\n\nconst getAllCorrectness = (answers, responses) =>\n (answers || []).map((answer) => ({\n ...answer,\n isCorrect: ((responses[answer.containerIndex] && responses[answer.containerIndex].images) || []).includes(\n answer.value,\n ),\n }));\n\nconst getValidAnswer = (answer, response) =>\n ((response[answer.containerIndex] && response[answer.containerIndex].images) || []).filter(\n (res) => res === answer.value,\n );\n\nexport const getAllUniqueCorrectness = (answers, validResponses) => {\n let allCorrectness = getAllCorrectness(answers, validResponses);\n\n answers.forEach((answer1) => {\n const valuesToParse = answers.filter(\n (answer2) => answer2.value === answer1.value && answer2.containerIndex === answer1.containerIndex,\n );\n\n if (valuesToParse.length > 1) {\n // point only to duplicates but first\n valuesToParse.shift();\n // mark duplicates as incorrect\n valuesToParse.forEach((value, index) => {\n allCorrectness = (allCorrectness || []).map((finalAnswer) => {\n if (finalAnswer.id === value.id) {\n let valid = getValidAnswer(finalAnswer, validResponses);\n return {\n ...finalAnswer,\n isCorrect: valid.length > index + 1,\n };\n }\n return finalAnswer;\n });\n });\n }\n });\n return allCorrectness;\n};\n"],"file":"utils.js"}
|
package/controller/src/index.js
CHANGED
|
@@ -1,22 +1,16 @@
|
|
|
1
1
|
import debug from 'debug';
|
|
2
|
-
import isEmpty from 'lodash/isEmpty';
|
|
3
|
-
import shuffle from 'lodash/shuffle';
|
|
4
2
|
import { camelizeKeys } from 'humps';
|
|
5
3
|
import { partialScoring } from '@pie-lib/pie-toolbox/controller-utils';
|
|
4
|
+
import { cloneDeep, isEmpty, shuffle } from 'lodash';
|
|
6
5
|
|
|
6
|
+
import defaults from './defaults';
|
|
7
7
|
import { getAllUniqueCorrectness } from './utils';
|
|
8
|
-
import { cloneDeep } from 'lodash';
|
|
9
8
|
|
|
10
9
|
const log = debug('pie-elements:image-cloze-association:controller');
|
|
11
10
|
|
|
12
|
-
export const normalize = (question) => ({
|
|
13
|
-
rationaleEnabled: true,
|
|
14
|
-
teacherInstructionsEnabled: true,
|
|
15
|
-
studentInstructionsEnabled: true,
|
|
16
|
-
...question,
|
|
17
|
-
});
|
|
11
|
+
export const normalize = (question) => ({ ...defaults, ...question });
|
|
18
12
|
|
|
19
|
-
export
|
|
13
|
+
export const model = (question, session, env) => {
|
|
20
14
|
const questionNormalized = normalize(question);
|
|
21
15
|
const questionCamelized = camelizeKeys(questionNormalized);
|
|
22
16
|
|
|
@@ -44,9 +38,10 @@ export function model(question, session, env) {
|
|
|
44
38
|
|
|
45
39
|
resolve(out);
|
|
46
40
|
});
|
|
47
|
-
}
|
|
41
|
+
};
|
|
48
42
|
|
|
49
|
-
export const isResponseCorrect = (
|
|
43
|
+
export const isResponseCorrect = (correctResponses, session) => {
|
|
44
|
+
const responses = cloneDeep(correctResponses);
|
|
50
45
|
let isCorrect = true;
|
|
51
46
|
let totalValidResponses = 0;
|
|
52
47
|
|
|
@@ -58,15 +53,19 @@ export const isResponseCorrect = (responses, session) => {
|
|
|
58
53
|
|
|
59
54
|
if (session.answers && totalValidResponses === session.answers.length) {
|
|
60
55
|
session.answers.forEach((answer) => {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
) {
|
|
56
|
+
const index = (responses[answer.containerIndex]?.images || []).indexOf(answer.value);
|
|
57
|
+
|
|
58
|
+
if (index >= 0) {
|
|
59
|
+
// remove response from correct responses array to ensure that duplicates are evaluated correctly
|
|
60
|
+
responses[answer.containerIndex].images.splice(index, 1);
|
|
61
|
+
} else {
|
|
64
62
|
isCorrect = false;
|
|
65
63
|
}
|
|
66
64
|
});
|
|
67
65
|
} else {
|
|
68
66
|
isCorrect = false;
|
|
69
67
|
}
|
|
68
|
+
|
|
70
69
|
return isCorrect;
|
|
71
70
|
};
|
|
72
71
|
|
|
@@ -172,7 +171,7 @@ const getScore = (config, session, env = {}) => {
|
|
|
172
171
|
return isPartialScoring ? getPartialScore(config, session) : correct ? 1 : 0;
|
|
173
172
|
};
|
|
174
173
|
|
|
175
|
-
export
|
|
174
|
+
export const outcome = (config, session, env = {}) => {
|
|
176
175
|
return new Promise((resolve) => {
|
|
177
176
|
log('outcome...');
|
|
178
177
|
if (!session || isEmpty(session)) {
|
|
@@ -186,7 +185,7 @@ export function outcome(config, session, env = {}) {
|
|
|
186
185
|
resolve({ score });
|
|
187
186
|
}
|
|
188
187
|
});
|
|
189
|
-
}
|
|
188
|
+
};
|
|
190
189
|
|
|
191
190
|
export const createCorrectResponseSession = (question, env) => {
|
|
192
191
|
return new Promise((resolve) => {
|
package/controller/src/utils.js
CHANGED
|
@@ -1,10 +1,17 @@
|
|
|
1
|
-
|
|
1
|
+
// functions also used in src/utils-correctness.js
|
|
2
|
+
|
|
3
|
+
const getAllCorrectness = (answers, responses) =>
|
|
4
|
+
(answers || []).map((answer) => ({
|
|
2
5
|
...answer,
|
|
3
|
-
isCorrect: (responses[answer.containerIndex] && responses[answer.containerIndex].images || []).includes(
|
|
4
|
-
|
|
6
|
+
isCorrect: ((responses[answer.containerIndex] && responses[answer.containerIndex].images) || []).includes(
|
|
7
|
+
answer.value,
|
|
8
|
+
),
|
|
9
|
+
}));
|
|
5
10
|
|
|
6
11
|
const getValidAnswer = (answer, response) =>
|
|
7
|
-
(response[answer.containerIndex] && response[answer.containerIndex].images || []).filter(
|
|
12
|
+
((response[answer.containerIndex] && response[answer.containerIndex].images) || []).filter(
|
|
13
|
+
(res) => res === answer.value,
|
|
14
|
+
);
|
|
8
15
|
|
|
9
16
|
export const getAllUniqueCorrectness = (answers, validResponses) => {
|
|
10
17
|
let allCorrectness = getAllCorrectness(answers, validResponses);
|
package/docs/demo/generate.js
CHANGED
|
@@ -43,7 +43,7 @@ exports.model = (id, element) => ({
|
|
|
43
43
|
metadatadistractor_rationale:
|
|
44
44
|
'<p>A correct response is shown below. This response best shows how this decision will likely affect the number tire pieces collected.<img alt="image 03de38019abe41b1bc95d1199658327f" id="03de38019abe41b1bc95d1199658327f" src="https://localhost:8443/ia/image/03de38019abe41b1bc95d1199658327f" /></p>',
|
|
45
45
|
ui_style: {
|
|
46
|
-
|
|
46
|
+
possibility_list_position: 'bottom',
|
|
47
47
|
// this is not used
|
|
48
48
|
fontsize: 'small',
|
|
49
49
|
},
|
package/lib/utils-correctness.js
CHANGED
|
@@ -15,6 +15,7 @@ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (O
|
|
|
15
15
|
|
|
16
16
|
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; }
|
|
17
17
|
|
|
18
|
+
// functions also used in controller/src/utils.js
|
|
18
19
|
var getAllCorrectAnswers = function getAllCorrectAnswers(answers, responses) {
|
|
19
20
|
return (answers || []).map(function (answer) {
|
|
20
21
|
return _objectSpread(_objectSpread({}, answer), {}, {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/utils-correctness.js"],"names":["getAllCorrectAnswers","answers","responses","map","answer","isCorrect","containerIndex","images","includes","value","getValidAnswer","response","filter","res","getUniqueCorrectAnswers","validResponses","finalAnswers","forEach","answer1","valuesToParse","answer2","length","shift","index","finalAnswer","id","valid","getUnansweredAnswers","validation","validResponse","reduce","unanswered","isAnswered","find","undefined","hidden","getAnswersCorrectness","altResponses","allCorrect","uniqueAnswers","noOfCorrect","altUniqueStack","altResponse","altValue","altAllCorrect","sort","a","b","c"],"mappings":";;;;;;;;;;;;;;;;;AAAA,IAAMA,oBAAoB,GAAG,SAAvBA,oBAAuB,CAACC,OAAD,EAAUC,SAAV;AAAA,SAC3B,CAACD,OAAO,IAAI,EAAZ,EAAgBE,GAAhB,CAAoB,UAACC,MAAD;AAAA,2CACfA,MADe;AAElBC,MAAAA,SAAS,EAAE,
|
|
1
|
+
{"version":3,"sources":["../src/utils-correctness.js"],"names":["getAllCorrectAnswers","answers","responses","map","answer","isCorrect","containerIndex","images","includes","value","getValidAnswer","response","filter","res","getUniqueCorrectAnswers","validResponses","finalAnswers","forEach","answer1","valuesToParse","answer2","length","shift","index","finalAnswer","id","valid","getUnansweredAnswers","validation","validResponse","reduce","unanswered","isAnswered","find","undefined","hidden","getAnswersCorrectness","altResponses","allCorrect","uniqueAnswers","noOfCorrect","altUniqueStack","altResponse","altValue","altAllCorrect","sort","a","b","c"],"mappings":"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","sourcesContent":["// functions also used in controller/src/utils.js\n\nconst getAllCorrectAnswers = (answers, responses) =>\n (answers || []).map((answer) => ({\n ...answer,\n isCorrect: ((responses[answer.containerIndex] && responses[answer.containerIndex].images) || []).includes(\n answer.value,\n ),\n }));\n\nconst getValidAnswer = (answer, response) =>\n (response[answer.containerIndex].images || []).filter((res) => res === answer.value);\n\nconst getUniqueCorrectAnswers = (answers, validResponses) => {\n let finalAnswers = answers;\n\n answers.forEach((answer1) => {\n const valuesToParse = answers.filter(\n (answer2) => answer2.value === answer1.value && answer2.containerIndex === answer1.containerIndex,\n );\n\n if (valuesToParse.length > 1) {\n // point only to duplicates but first\n valuesToParse.shift();\n // mark duplicates as incorrect\n valuesToParse.forEach((value, index) => {\n finalAnswers = (finalAnswers || []).map((finalAnswer) => {\n if (finalAnswer.id === value.id) {\n let valid = getValidAnswer(finalAnswer, validResponses);\n\n return {\n ...finalAnswer,\n isCorrect: valid.length > index + 1,\n };\n }\n return finalAnswer;\n });\n });\n }\n });\n return finalAnswers;\n};\n\nexport const getUnansweredAnswers = (answers, validation) => {\n const { validResponse: { value } = {} } = validation;\n\n return (value || []).reduce((unanswered, response, index) => {\n const isAnswered = !!answers.find((answer) => answer.containerIndex === index);\n response.images = response.images || [];\n\n if (!isAnswered) {\n return [\n ...unanswered,\n {\n id: `unanswered-${index}`,\n value: response.images[0] || '',\n containerIndex: index,\n isCorrect: !response.images.length ? undefined : false,\n hidden: true,\n },\n ];\n }\n\n return unanswered;\n }, []);\n};\n\nexport const getAnswersCorrectness = (answers, validation) => {\n const {\n validResponse: { value },\n altResponses,\n } = validation;\n\n const allCorrect = getAllCorrectAnswers(answers, value);\n const uniqueAnswers = getUniqueCorrectAnswers(allCorrect, value);\n const noOfCorrect = uniqueAnswers.filter((answer) => answer.isCorrect).length;\n\n // Look for alternate correct responses if there are incorrect responses.\n if (noOfCorrect < uniqueAnswers.length && altResponses && altResponses.length) {\n const altUniqueStack = (altResponses || []).map((altResponse) => {\n const altValue = altResponse.value;\n\n const altAllCorrect = getAllCorrectAnswers(answers, altValue);\n return getUniqueCorrectAnswers(altAllCorrect, altValue);\n });\n // Return the one with most correct answers.\n return altUniqueStack.sort((a, b) => b.filter((c) => c.isCorrect).length - a.filter((c) => c.isCorrect).length)[0];\n }\n return uniqueAnswers;\n};\n"],"file":"utils-correctness.js"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pie-element/image-cloze-association",
|
|
3
|
-
"version": "5.21.1-next.
|
|
3
|
+
"version": "5.21.1-next.23+a082abd84",
|
|
4
4
|
"description": "",
|
|
5
5
|
"repository": "pie-framework/pie-elements",
|
|
6
6
|
"publishConfig": {
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
},
|
|
19
19
|
"author": "pie framework developers",
|
|
20
20
|
"license": "ISC",
|
|
21
|
-
"gitHead": "
|
|
21
|
+
"gitHead": "a082abd841f72fb1dfabf5b23a2b48e90ba05ec2",
|
|
22
22
|
"scripts": {
|
|
23
23
|
"postpublish": "../../scripts/postpublish"
|
|
24
24
|
},
|
package/src/utils-correctness.js
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
|
+
// functions also used in controller/src/utils.js
|
|
2
|
+
|
|
1
3
|
const getAllCorrectAnswers = (answers, responses) =>
|
|
2
4
|
(answers || []).map((answer) => ({
|
|
3
5
|
...answer,
|
|
4
|
-
isCorrect: (responses[answer.containerIndex] && responses[answer.containerIndex].images || []).includes(
|
|
6
|
+
isCorrect: ((responses[answer.containerIndex] && responses[answer.containerIndex].images) || []).includes(
|
|
7
|
+
answer.value,
|
|
8
|
+
),
|
|
5
9
|
}));
|
|
6
10
|
|
|
7
11
|
const getValidAnswer = (answer, response) =>
|