@pie-element/graphing-solution-set 6.1.2-next.1 → 6.1.2
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/CHANGELOG.json +1 -0
- package/CHANGELOG.md +856 -0
- package/LICENSE.md +5 -0
- package/README.md +20 -0
- package/configure/CHANGELOG.json +1 -0
- package/configure/CHANGELOG.md +816 -0
- package/configure/lib/configure.js +312 -0
- package/configure/lib/configure.js.map +1 -0
- package/configure/lib/correct-response.js +435 -0
- package/configure/lib/correct-response.js.map +1 -0
- package/configure/lib/defaults.js +357 -0
- package/configure/lib/defaults.js.map +1 -0
- package/configure/lib/graphing-config.js +408 -0
- package/configure/lib/graphing-config.js.map +1 -0
- package/configure/lib/index.js +163 -0
- package/configure/lib/index.js.map +1 -0
- package/configure/lib/utils.js +630 -0
- package/configure/lib/utils.js.map +1 -0
- package/configure/package.json +29 -0
- package/controller/CHANGELOG.json +1 -0
- package/controller/CHANGELOG.md +675 -0
- package/controller/lib/defaults.js +69 -0
- package/controller/lib/defaults.js.map +1 -0
- package/controller/lib/index.js +351 -0
- package/controller/lib/index.js.map +1 -0
- package/controller/lib/utils.js +212 -0
- package/controller/lib/utils.js.map +1 -0
- package/controller/package.json +22 -0
- package/demo-gss.gif +0 -0
- package/docs/config-schema.json +1560 -0
- package/docs/config-schema.json.md +1114 -0
- package/docs/demo/config.js +8 -0
- package/docs/demo/generate.js +54 -0
- package/docs/demo/index.html +1 -0
- package/docs/demo/session.js +6 -0
- package/docs/pie-schema.json +1800 -0
- package/docs/pie-schema.json.md +952 -0
- package/lib/index.js +164 -0
- package/lib/index.js.map +1 -0
- package/lib/main.js +355 -0
- package/lib/main.js.map +1 -0
- package/lib/utils.js +515 -0
- package/lib/utils.js.map +1 -0
- package/package.json +23 -86
- package/configure.js +0 -2
- package/controller.js +0 -1
- package/dist/author/configure.d.ts +0 -26
- package/dist/author/configure.js +0 -190
- package/dist/author/correct-response.d.ts +0 -33
- package/dist/author/correct-response.js +0 -206
- package/dist/author/defaults.d.ts +0 -238
- package/dist/author/defaults.js +0 -339
- package/dist/author/graphing-config.d.ts +0 -33
- package/dist/author/graphing-config.js +0 -237
- package/dist/author/index.d.ts +0 -62
- package/dist/author/index.js +0 -87
- package/dist/author/utils.d.ts +0 -46
- package/dist/author/utils.js +0 -474
- package/dist/browser/author/index.js +0 -1942
- package/dist/browser/author/index.js.map +0 -1
- package/dist/browser/browser-pUycHh7Y.js +0 -348
- package/dist/browser/browser-pUycHh7Y.js.map +0 -1
- package/dist/browser/controller/index.js +0 -193
- package/dist/browser/controller/index.js.map +0 -1
- package/dist/browser/delivery/index.js +0 -782
- package/dist/browser/delivery/index.js.map +0 -1
- package/dist/browser/dist-BxTk7Laj.js +0 -57671
- package/dist/browser/dist-BxTk7Laj.js.map +0 -1
- package/dist/browser/graphing-solution-set.css +0 -2
- package/dist/controller/defaults.d.ts +0 -64
- package/dist/controller/defaults.js +0 -54
- package/dist/controller/index.d.ts +0 -24
- package/dist/controller/index.js +0 -110
- package/dist/controller/utils.d.ts +0 -20
- package/dist/controller/utils.js +0 -39
- package/dist/delivery/index.d.ts +0 -22
- package/dist/delivery/index.js +0 -62
- package/dist/delivery/main.d.ts +0 -31
- package/dist/delivery/main.js +0 -198
- package/dist/delivery/utils.d.ts +0 -12
- package/dist/delivery/utils.js +0 -220
- package/dist/graphing-solution-set.css +0 -2
- package/dist/index.d.ts +0 -1
- package/dist/index.iife.d.ts +0 -8
- package/dist/index.iife.js +0 -405
- package/dist/index.js +0 -2
- package/dist/runtime-support.d.ts +0 -12
- package/dist/runtime-support.js +0 -12
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
/*
|
|
8
|
+
* This file contains the default configuration for the Graphing Solution Set Item Type.
|
|
9
|
+
* Model is similar to the one used in graphing item type except for the gssLineData object which handles
|
|
10
|
+
* the configuration for the lines and the solution set.
|
|
11
|
+
*
|
|
12
|
+
* Same model is used in configure/src default.js
|
|
13
|
+
* */
|
|
14
|
+
var _default = exports.default = {
|
|
15
|
+
answers: {
|
|
16
|
+
correctAnswer: {
|
|
17
|
+
name: 'Correct Answer',
|
|
18
|
+
marks: []
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
arrows: {
|
|
22
|
+
left: true,
|
|
23
|
+
right: true,
|
|
24
|
+
up: true,
|
|
25
|
+
down: true
|
|
26
|
+
},
|
|
27
|
+
marks: [],
|
|
28
|
+
defaultGridConfiguration: 0,
|
|
29
|
+
domain: {
|
|
30
|
+
min: -5,
|
|
31
|
+
max: 5,
|
|
32
|
+
step: 1,
|
|
33
|
+
labelStep: 1,
|
|
34
|
+
axisLabel: 'x'
|
|
35
|
+
},
|
|
36
|
+
graph: {
|
|
37
|
+
width: 500,
|
|
38
|
+
height: 500
|
|
39
|
+
},
|
|
40
|
+
gssLineData: {
|
|
41
|
+
numberOfLines: 1,
|
|
42
|
+
selectedTool: 'lineA',
|
|
43
|
+
sections: [],
|
|
44
|
+
lineA: {
|
|
45
|
+
lineType: 'Solid'
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
includeAxes: true,
|
|
49
|
+
labels: {},
|
|
50
|
+
labelsEnabled: true,
|
|
51
|
+
padding: true,
|
|
52
|
+
prompt: '',
|
|
53
|
+
range: {
|
|
54
|
+
min: -5,
|
|
55
|
+
max: 5,
|
|
56
|
+
step: 1,
|
|
57
|
+
labelStep: 1,
|
|
58
|
+
axisLabel: 'y'
|
|
59
|
+
},
|
|
60
|
+
rationale: '',
|
|
61
|
+
standardGrid: false,
|
|
62
|
+
title: '',
|
|
63
|
+
coordinatesOnHover: false,
|
|
64
|
+
promptEnabled: true,
|
|
65
|
+
rationaleEnabled: true,
|
|
66
|
+
teacherInstructionsEnabled: true,
|
|
67
|
+
studentInstructionsEnabled: true
|
|
68
|
+
};
|
|
69
|
+
//# sourceMappingURL=defaults.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"defaults.js","names":["_default","exports","default","answers","correctAnswer","name","marks","arrows","left","right","up","down","defaultGridConfiguration","domain","min","max","step","labelStep","axisLabel","graph","width","height","gssLineData","numberOfLines","selectedTool","sections","lineA","lineType","includeAxes","labels","labelsEnabled","padding","prompt","range","rationale","standardGrid","title","coordinatesOnHover","promptEnabled","rationaleEnabled","teacherInstructionsEnabled","studentInstructionsEnabled"],"sources":["../src/defaults.js"],"sourcesContent":["/*\n * This file contains the default configuration for the Graphing Solution Set Item Type.\n * Model is similar to the one used in graphing item type except for the gssLineData object which handles\n * the configuration for the lines and the solution set.\n *\n * Same model is used in configure/src default.js\n * */\nexport default {\n answers: {\n correctAnswer: {\n name: 'Correct Answer',\n marks: [],\n },\n },\n arrows: {\n left: true,\n right: true,\n up: true,\n down: true,\n },\n marks: [],\n defaultGridConfiguration: 0,\n domain: {\n min: -5,\n max: 5,\n step: 1,\n labelStep: 1,\n axisLabel: 'x',\n },\n graph: {\n width: 500,\n height: 500,\n },\n gssLineData: {\n numberOfLines: 1,\n selectedTool: 'lineA',\n sections: [],\n lineA: {\n lineType: 'Solid',\n },\n },\n includeAxes: true,\n labels: {},\n labelsEnabled: true,\n padding: true,\n prompt: '',\n range: {\n min: -5,\n max: 5,\n step: 1,\n labelStep: 1,\n axisLabel: 'y',\n },\n rationale: '',\n standardGrid: false,\n title: '',\n coordinatesOnHover: false,\n promptEnabled: true,\n rationaleEnabled: true,\n teacherInstructionsEnabled: true,\n studentInstructionsEnabled: true,\n};\n"],"mappings":";;;;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AANA,IAAAA,QAAA,GAAAC,OAAA,CAAAC,OAAA,GAOe;EACbC,OAAO,EAAE;IACPC,aAAa,EAAE;MACbC,IAAI,EAAE,gBAAgB;MACtBC,KAAK,EAAE;IACT;EACF,CAAC;EACDC,MAAM,EAAE;IACNC,IAAI,EAAE,IAAI;IACVC,KAAK,EAAE,IAAI;IACXC,EAAE,EAAE,IAAI;IACRC,IAAI,EAAE;EACR,CAAC;EACDL,KAAK,EAAE,EAAE;EACTM,wBAAwB,EAAE,CAAC;EAC3BC,MAAM,EAAE;IACNC,GAAG,EAAE,CAAC,CAAC;IACPC,GAAG,EAAE,CAAC;IACNC,IAAI,EAAE,CAAC;IACPC,SAAS,EAAE,CAAC;IACZC,SAAS,EAAE;EACb,CAAC;EACDC,KAAK,EAAE;IACLC,KAAK,EAAE,GAAG;IACVC,MAAM,EAAE;EACV,CAAC;EACDC,WAAW,EAAE;IACXC,aAAa,EAAE,CAAC;IAChBC,YAAY,EAAE,OAAO;IACrBC,QAAQ,EAAE,EAAE;IACZC,KAAK,EAAE;MACLC,QAAQ,EAAE;IACZ;EACF,CAAC;EACDC,WAAW,EAAE,IAAI;EACjBC,MAAM,EAAE,CAAC,CAAC;EACVC,aAAa,EAAE,IAAI;EACnBC,OAAO,EAAE,IAAI;EACbC,MAAM,EAAE,EAAE;EACVC,KAAK,EAAE;IACLnB,GAAG,EAAE,CAAC,CAAC;IACPC,GAAG,EAAE,CAAC;IACNC,IAAI,EAAE,CAAC;IACPC,SAAS,EAAE,CAAC;IACZC,SAAS,EAAE;EACb,CAAC;EACDgB,SAAS,EAAE,EAAE;EACbC,YAAY,EAAE,KAAK;EACnBC,KAAK,EAAE,EAAE;EACTC,kBAAkB,EAAE,KAAK;EACzBC,aAAa,EAAE,IAAI;EACnBC,gBAAgB,EAAE,IAAI;EACtBC,0BAA0B,EAAE,IAAI;EAChCC,0BAA0B,EAAE;AAC9B,CAAC","ignoreList":[]}
|
|
@@ -0,0 +1,351 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.getBestAnswer = exports.getAnswerCorrected = exports.createCorrectResponseSession = exports.compareMarks = void 0;
|
|
8
|
+
exports.model = model;
|
|
9
|
+
exports.normalize = void 0;
|
|
10
|
+
exports.outcome = outcome;
|
|
11
|
+
exports.validate = void 0;
|
|
12
|
+
var _debug = _interopRequireDefault(require("debug"));
|
|
13
|
+
var _lodashEs = require("lodash-es");
|
|
14
|
+
var _defaults = _interopRequireDefault(require("./defaults"));
|
|
15
|
+
var _utils = require("./utils");
|
|
16
|
+
const log = (0, _debug.default)('@pie-element:graphing-solution-set:controller');
|
|
17
|
+
const initializeGraphMap = () => ({
|
|
18
|
+
line: []
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
/*
|
|
22
|
+
* Function to compare two marks
|
|
23
|
+
* @param {Object} mark1 - first mark
|
|
24
|
+
* @param {Object} mark2 - second mark
|
|
25
|
+
* */
|
|
26
|
+
const compareMarks = (mark1, mark2) => {
|
|
27
|
+
// marks can be compared with equalMarks[type] function only if they have the same type;
|
|
28
|
+
// if type is different, they are clearly not equal
|
|
29
|
+
return !!(mark1 && mark2 && mark1.type === mark2.type && _utils.equalMarks[mark1.type] && _utils.equalMarks[mark1.type](mark1, mark2));
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
/*
|
|
33
|
+
* Function to get the corrected answer
|
|
34
|
+
* @param {Object} sessionAnswers - array of marks from session
|
|
35
|
+
* @param {Object} marks - array of marks from correct answer
|
|
36
|
+
* */
|
|
37
|
+
exports.compareMarks = compareMarks;
|
|
38
|
+
const getAnswerCorrected = ({
|
|
39
|
+
sessionAnswers,
|
|
40
|
+
marks: correctAnswers
|
|
41
|
+
}) => {
|
|
42
|
+
sessionAnswers = sessionAnswers || [];
|
|
43
|
+
correctAnswers = correctAnswers || [];
|
|
44
|
+
const rez = (0, _lodashEs.cloneDeep)(sessionAnswers).reduce((correctedAnswer, answer) => {
|
|
45
|
+
const answerIsCorrect = correctAnswers.find(mark => compareMarks(answer, mark));
|
|
46
|
+
answer.correctness = answerIsCorrect ? 'correct' : 'incorrect';
|
|
47
|
+
return [...correctedAnswer, answer];
|
|
48
|
+
}, []);
|
|
49
|
+
// add missing objects from correct answer
|
|
50
|
+
const missingAnswers = (0, _lodashEs.cloneDeep)(correctAnswers).reduce((correctedAnswer, answer) => {
|
|
51
|
+
const answerIndex = sessionAnswers.find(mark => compareMarks(answer, mark));
|
|
52
|
+
if (!answerIndex) {
|
|
53
|
+
// means that corrected answer is missing from session, so we mark it as missing object
|
|
54
|
+
return [...correctedAnswer, {
|
|
55
|
+
...answer,
|
|
56
|
+
correctness: 'missing'
|
|
57
|
+
}];
|
|
58
|
+
}
|
|
59
|
+
return correctedAnswer;
|
|
60
|
+
}, []);
|
|
61
|
+
return [...rez, ...missingAnswers];
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
/*
|
|
65
|
+
* Function to get the best answer
|
|
66
|
+
* @param {Object} question - question object
|
|
67
|
+
* @param {Object} session - session object
|
|
68
|
+
* @param {Object} env - env object
|
|
69
|
+
* */
|
|
70
|
+
exports.getAnswerCorrected = getAnswerCorrected;
|
|
71
|
+
const getBestAnswer = (question, session, env = {}) => {
|
|
72
|
+
// questionPossibleAnswers contains all possible answers (correct response and alternates);
|
|
73
|
+
let {
|
|
74
|
+
answers: questionPossibleAnswers = {},
|
|
75
|
+
scoringType
|
|
76
|
+
} = question || {};
|
|
77
|
+
let {
|
|
78
|
+
answer
|
|
79
|
+
} = session || {};
|
|
80
|
+
// filter the incomplete objects
|
|
81
|
+
Object.entries(questionPossibleAnswers || {}).forEach(([key, value]) => questionPossibleAnswers[key] = {
|
|
82
|
+
...value,
|
|
83
|
+
marks: value?.marks.filter(mark => !mark.building)
|
|
84
|
+
});
|
|
85
|
+
// initialize answer if no values
|
|
86
|
+
answer = answer || [];
|
|
87
|
+
// initialize one possible answer if no values
|
|
88
|
+
if ((0, _lodashEs.isEmpty)(questionPossibleAnswers)) {
|
|
89
|
+
questionPossibleAnswers = {
|
|
90
|
+
correctAnswer: initializeGraphMap()
|
|
91
|
+
};
|
|
92
|
+
} else {
|
|
93
|
+
questionPossibleAnswers = {
|
|
94
|
+
correctAnswer: questionPossibleAnswers.correctAnswer,
|
|
95
|
+
...(0, _utils.sortedAnswers)(questionPossibleAnswers)
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
// student's answers without DUPLICATES
|
|
99
|
+
const sessionAnswers = (0, _lodashEs.uniqWith)(answer, compareMarks);
|
|
100
|
+
// array of possible answers entries
|
|
101
|
+
const possibleAnswers = Object.entries(questionPossibleAnswers);
|
|
102
|
+
return possibleAnswers.reduce((acc, entry) => {
|
|
103
|
+
// iterating each possible answer (main + alternates)
|
|
104
|
+
const possibleAnswerKey = entry[0];
|
|
105
|
+
const possibleAnswer = entry[1] || {};
|
|
106
|
+
let {
|
|
107
|
+
marks
|
|
108
|
+
} = possibleAnswer;
|
|
109
|
+
if (!marks || !marks.length) {
|
|
110
|
+
return acc;
|
|
111
|
+
}
|
|
112
|
+
// returns array of marks, each having 'correctness' property
|
|
113
|
+
const correctedAnswer = getAnswerCorrected({
|
|
114
|
+
sessionAnswers,
|
|
115
|
+
marks
|
|
116
|
+
});
|
|
117
|
+
const correctMarks = correctedAnswer.filter(answer => answer.correctness === 'correct');
|
|
118
|
+
// filter out missing objects because they do not affect the calculation of the score
|
|
119
|
+
// only correct and incorrect are needed
|
|
120
|
+
const scoredCorrectedAnswer = correctedAnswer.filter(answer => answer.correctness !== 'missing');
|
|
121
|
+
const maxScore = marks.length;
|
|
122
|
+
let score = correctMarks.length;
|
|
123
|
+
// if extra placements
|
|
124
|
+
if (scoredCorrectedAnswer.length > maxScore) {
|
|
125
|
+
score -= scoredCorrectedAnswer.length - maxScore;
|
|
126
|
+
}
|
|
127
|
+
if (score < 0) {
|
|
128
|
+
score = 0;
|
|
129
|
+
}
|
|
130
|
+
if (score / maxScore > acc.bestScore || !acc.foundOneSolution) {
|
|
131
|
+
acc.bestScore = Math.floor(score / maxScore);
|
|
132
|
+
acc.bestScoreAnswerKey = possibleAnswerKey;
|
|
133
|
+
acc.answersCorrected = correctedAnswer;
|
|
134
|
+
acc.foundOneSolution = true;
|
|
135
|
+
}
|
|
136
|
+
return acc;
|
|
137
|
+
}, {
|
|
138
|
+
bestScore: 0,
|
|
139
|
+
bestScoreAnswerKey: null,
|
|
140
|
+
// initially we just suppose all the answers are incorrect
|
|
141
|
+
answersCorrected: (0, _lodashEs.cloneDeep)(sessionAnswers).map(answer => ({
|
|
142
|
+
...answer,
|
|
143
|
+
correctness: 'incorrect'
|
|
144
|
+
})),
|
|
145
|
+
foundOneSolution: false
|
|
146
|
+
});
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
/*
|
|
150
|
+
* Constant normalize
|
|
151
|
+
* @param {Object} question - question object
|
|
152
|
+
* */
|
|
153
|
+
exports.getBestAnswer = getBestAnswer;
|
|
154
|
+
const normalize = question => ({
|
|
155
|
+
..._defaults.default,
|
|
156
|
+
...question
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
/*
|
|
160
|
+
* Function to set model
|
|
161
|
+
* @param {Object} question - question object
|
|
162
|
+
* @param {Object} session - session object
|
|
163
|
+
* @param {Object} env - env object
|
|
164
|
+
* */
|
|
165
|
+
exports.normalize = normalize;
|
|
166
|
+
function model(question, session, env) {
|
|
167
|
+
return new Promise(resolve => {
|
|
168
|
+
const normalizedQuestion = normalize(question);
|
|
169
|
+
// ensure removing of invalid answers
|
|
170
|
+
// need this if undo redo was last operation
|
|
171
|
+
session.answer = (0, _utils.removeInvalidAnswers)(session.answer);
|
|
172
|
+
// console.log('normalizedQuestion', normalizedQuestion);
|
|
173
|
+
const {
|
|
174
|
+
defaultTool,
|
|
175
|
+
extraCSSRules,
|
|
176
|
+
prompt,
|
|
177
|
+
promptEnabled,
|
|
178
|
+
graph,
|
|
179
|
+
answers,
|
|
180
|
+
toolbarTools,
|
|
181
|
+
...questionProps
|
|
182
|
+
} = normalizedQuestion || {};
|
|
183
|
+
let {
|
|
184
|
+
arrows
|
|
185
|
+
} = normalizedQuestion;
|
|
186
|
+
const {
|
|
187
|
+
mode,
|
|
188
|
+
role
|
|
189
|
+
} = env || {};
|
|
190
|
+
|
|
191
|
+
// This is used for offering support for old models which have the property arrows: boolean
|
|
192
|
+
// Same thing is set in authoring : packages/graphing/configure/src/configure.jsx - componentDidMount
|
|
193
|
+
if (typeof arrows === 'boolean') {
|
|
194
|
+
if (arrows) {
|
|
195
|
+
arrows = {
|
|
196
|
+
left: true,
|
|
197
|
+
right: true,
|
|
198
|
+
up: true,
|
|
199
|
+
down: true
|
|
200
|
+
};
|
|
201
|
+
} else {
|
|
202
|
+
arrows = {
|
|
203
|
+
left: false,
|
|
204
|
+
right: false,
|
|
205
|
+
up: false,
|
|
206
|
+
down: false
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
const base = {
|
|
211
|
+
...questionProps,
|
|
212
|
+
answers,
|
|
213
|
+
arrows,
|
|
214
|
+
defaultTool: 'line',
|
|
215
|
+
disabled: env.mode !== 'gather',
|
|
216
|
+
prompt: promptEnabled ? prompt : null,
|
|
217
|
+
rationale: null,
|
|
218
|
+
size: graph,
|
|
219
|
+
showToggle: env.mode === 'evaluate' && !(0, _lodashEs.isEmpty)(answers) && answers.correctAnswer && answers.correctAnswer.marks && !(0, _lodashEs.isEmpty)(answers.correctAnswer.marks),
|
|
220
|
+
teacherInstructions: null,
|
|
221
|
+
toolbarTools,
|
|
222
|
+
extraCSSRules
|
|
223
|
+
};
|
|
224
|
+
if (role === 'instructor' && (mode === 'view' || mode === 'evaluate')) {
|
|
225
|
+
const {
|
|
226
|
+
rationale,
|
|
227
|
+
rationaleEnabled,
|
|
228
|
+
teacherInstructions,
|
|
229
|
+
teacherInstructionsEnabled
|
|
230
|
+
} = normalizedQuestion || {};
|
|
231
|
+
base.rationale = rationaleEnabled ? rationale : null;
|
|
232
|
+
base.teacherInstructions = teacherInstructionsEnabled ? teacherInstructions : null;
|
|
233
|
+
}
|
|
234
|
+
if (mode === 'evaluate') {
|
|
235
|
+
if (!(0, _lodashEs.isEmpty)(answers) && answers.correctAnswer && answers.correctAnswer.marks && !(0, _lodashEs.isEmpty)(answers.correctAnswer.marks)) {
|
|
236
|
+
const {
|
|
237
|
+
answersCorrected,
|
|
238
|
+
bestScoreAnswerKey,
|
|
239
|
+
bestScore
|
|
240
|
+
} = getBestAnswer(normalizedQuestion, session, env);
|
|
241
|
+
// array of marks from session with 'correctness' property set
|
|
242
|
+
base.answersCorrected = answersCorrected;
|
|
243
|
+
base.correctResponse = bestScoreAnswerKey ? (answers[bestScoreAnswerKey] || {}).marks : [];
|
|
244
|
+
base.showToggle = base.showToggle && bestScore !== 1;
|
|
245
|
+
} else {
|
|
246
|
+
base.answersCorrected = session && session.answer || [];
|
|
247
|
+
base.correctResponse = [];
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
log('base: ', base);
|
|
251
|
+
resolve(base);
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
/*
|
|
256
|
+
* Function to check the outcome
|
|
257
|
+
* @param {Object} question - question object
|
|
258
|
+
* @param {Object} session - session object
|
|
259
|
+
* @param {Object} env - env object
|
|
260
|
+
* */
|
|
261
|
+
function outcome(question, session, env = {}) {
|
|
262
|
+
return new Promise(resolve => {
|
|
263
|
+
if (!session || (0, _lodashEs.isEmpty)(session)) {
|
|
264
|
+
resolve({
|
|
265
|
+
score: 0,
|
|
266
|
+
empty: true
|
|
267
|
+
});
|
|
268
|
+
}
|
|
269
|
+
if (env.mode !== 'evaluate' || (0, _lodashEs.isEmpty)(question.answers) || question.answers && question.answers.correctAnswer && (0, _lodashEs.isEmpty)(question.answers.correctAnswer.marks)) {
|
|
270
|
+
resolve({
|
|
271
|
+
score: 0
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
const {
|
|
275
|
+
bestScore
|
|
276
|
+
} = getBestAnswer(question, session, env);
|
|
277
|
+
resolve({
|
|
278
|
+
score: bestScore
|
|
279
|
+
});
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
/*
|
|
284
|
+
* Constant to create correct response session
|
|
285
|
+
* @param {Object} question - question object
|
|
286
|
+
* @param {Object} env - env object
|
|
287
|
+
* */
|
|
288
|
+
const createCorrectResponseSession = (question, env) => {
|
|
289
|
+
return new Promise(resolve => {
|
|
290
|
+
if (env.mode !== 'evaluate' && env.role === 'instructor') {
|
|
291
|
+
const {
|
|
292
|
+
answers
|
|
293
|
+
} = question || {};
|
|
294
|
+
let marks = [];
|
|
295
|
+
if (answers && Object.values(answers)) {
|
|
296
|
+
const correctAnswer = answers.correctAnswer || Object.values(answers)[0] || {};
|
|
297
|
+
marks = correctAnswer.marks || [];
|
|
298
|
+
}
|
|
299
|
+
resolve({
|
|
300
|
+
answer: marks,
|
|
301
|
+
id: '1'
|
|
302
|
+
});
|
|
303
|
+
} else {
|
|
304
|
+
resolve(null);
|
|
305
|
+
}
|
|
306
|
+
});
|
|
307
|
+
};
|
|
308
|
+
|
|
309
|
+
/*
|
|
310
|
+
* Constant to validate model before saving item
|
|
311
|
+
* @param {Object} model - model object
|
|
312
|
+
* */
|
|
313
|
+
exports.createCorrectResponseSession = createCorrectResponseSession;
|
|
314
|
+
const validate = (model = {}) => {
|
|
315
|
+
const {
|
|
316
|
+
answers,
|
|
317
|
+
gssLineData
|
|
318
|
+
} = model;
|
|
319
|
+
const errors = {};
|
|
320
|
+
const correctAnswerErrors = {};
|
|
321
|
+
let found = false;
|
|
322
|
+
if (gssLineData.numberOfLines === 1) {
|
|
323
|
+
if (answers.correctAnswer.marks.length < 1) {
|
|
324
|
+
found = true;
|
|
325
|
+
correctAnswerErrors.correctAnswer = 'At least 1 line object should be defined.';
|
|
326
|
+
} else if (answers.correctAnswer.marks.length === 1 && answers.correctAnswer.marks[0].building) {
|
|
327
|
+
found = true;
|
|
328
|
+
correctAnswerErrors.correctAnswer = '1 or more graph object should be correctly defined.';
|
|
329
|
+
}
|
|
330
|
+
} else {
|
|
331
|
+
if (answers.correctAnswer.marks.length < 2) {
|
|
332
|
+
found = true;
|
|
333
|
+
correctAnswerErrors.correctAnswer = 'At least 2 line object should be defined.';
|
|
334
|
+
} else if (answers.correctAnswer.marks.length === 2) {
|
|
335
|
+
if (answers.correctAnswer.marks[0].building || answers.correctAnswer.marks[1].building) {
|
|
336
|
+
found = true;
|
|
337
|
+
correctAnswerErrors.correctAnswer = '1 or more graph object should be correctly defined.';
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
let polygon = answers.correctAnswer.marks.find(mark => mark.type === 'polygon');
|
|
342
|
+
if (!found && (!gssLineData.selectedTool === 'solutionSet' || !polygon)) {
|
|
343
|
+
correctAnswerErrors.correctAnswer = 'Please select a solution set for the graphing solution set item.';
|
|
344
|
+
}
|
|
345
|
+
if (!(0, _lodashEs.isEmpty)(correctAnswerErrors)) {
|
|
346
|
+
errors.correctAnswerErrors = correctAnswerErrors;
|
|
347
|
+
}
|
|
348
|
+
return errors;
|
|
349
|
+
};
|
|
350
|
+
exports.validate = validate;
|
|
351
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":["_debug","_interopRequireDefault","require","_lodashEs","_defaults","_utils","log","debug","initializeGraphMap","line","compareMarks","mark1","mark2","type","equalMarks","exports","getAnswerCorrected","sessionAnswers","marks","correctAnswers","rez","cloneDeep","reduce","correctedAnswer","answer","answerIsCorrect","find","mark","correctness","missingAnswers","answerIndex","getBestAnswer","question","session","env","answers","questionPossibleAnswers","scoringType","Object","entries","forEach","key","value","filter","building","isEmpty","correctAnswer","sortedAnswers","uniqWith","possibleAnswers","acc","entry","possibleAnswerKey","possibleAnswer","length","correctMarks","scoredCorrectedAnswer","maxScore","score","bestScore","foundOneSolution","Math","floor","bestScoreAnswerKey","answersCorrected","map","normalize","defaults","model","Promise","resolve","normalizedQuestion","removeInvalidAnswers","defaultTool","extraCSSRules","prompt","promptEnabled","graph","toolbarTools","questionProps","arrows","mode","role","left","right","up","down","base","disabled","rationale","size","showToggle","teacherInstructions","rationaleEnabled","teacherInstructionsEnabled","correctResponse","outcome","empty","createCorrectResponseSession","values","id","validate","gssLineData","errors","correctAnswerErrors","found","numberOfLines","polygon","selectedTool"],"sources":["../src/index.js"],"sourcesContent":["import debug from 'debug';\nimport { cloneDeep, isEmpty, uniqWith } from 'lodash-es';\nimport defaults from './defaults';\nimport { equalMarks, sortedAnswers, removeInvalidAnswers } from './utils';\n\nconst log = debug('@pie-element:graphing-solution-set:controller');\n\nconst initializeGraphMap = () => ({\n line: [],\n});\n\n/*\n * Function to compare two marks\n * @param {Object} mark1 - first mark\n * @param {Object} mark2 - second mark\n * */\nexport const compareMarks = (mark1, mark2) => {\n // marks can be compared with equalMarks[type] function only if they have the same type;\n // if type is different, they are clearly not equal\n return !!(\n mark1 &&\n mark2 &&\n mark1.type === mark2.type &&\n equalMarks[mark1.type] &&\n equalMarks[mark1.type](mark1, mark2)\n );\n};\n\n/*\n * Function to get the corrected answer\n * @param {Object} sessionAnswers - array of marks from session\n * @param {Object} marks - array of marks from correct answer\n * */\nexport const getAnswerCorrected = ({ sessionAnswers, marks: correctAnswers }) => {\n sessionAnswers = sessionAnswers || [];\n correctAnswers = correctAnswers || [];\n const rez = cloneDeep(sessionAnswers).reduce((correctedAnswer, answer) => {\n const answerIsCorrect = correctAnswers.find((mark) => compareMarks(answer, mark));\n answer.correctness = answerIsCorrect ? 'correct' : 'incorrect';\n return [...correctedAnswer, answer];\n }, []);\n // add missing objects from correct answer\n const missingAnswers = cloneDeep(correctAnswers).reduce((correctedAnswer, answer) => {\n const answerIndex = sessionAnswers.find((mark) => compareMarks(answer, mark));\n if (!answerIndex) {\n // means that corrected answer is missing from session, so we mark it as missing object\n return [...correctedAnswer, { ...answer, correctness: 'missing' }];\n }\n return correctedAnswer;\n }, []);\n return [...rez, ...missingAnswers];\n};\n\n/*\n * Function to get the best answer\n * @param {Object} question - question object\n * @param {Object} session - session object\n * @param {Object} env - env object\n * */\nexport const getBestAnswer = (question, session, env = {}) => {\n // questionPossibleAnswers contains all possible answers (correct response and alternates);\n let { answers: questionPossibleAnswers = {}, scoringType } = question || {};\n let { answer } = session || {};\n // filter the incomplete objects\n Object.entries(questionPossibleAnswers || {}).forEach(\n ([key, value]) =>\n (questionPossibleAnswers[key] = { ...value, marks: value?.marks.filter((mark) => !mark.building) }),\n );\n // initialize answer if no values\n answer = answer || [];\n // initialize one possible answer if no values\n if (isEmpty(questionPossibleAnswers)) {\n questionPossibleAnswers = { correctAnswer: initializeGraphMap() };\n } else {\n questionPossibleAnswers = {\n correctAnswer: questionPossibleAnswers.correctAnswer,\n ...sortedAnswers(questionPossibleAnswers),\n };\n }\n // student's answers without DUPLICATES\n const sessionAnswers = uniqWith(answer, compareMarks);\n // array of possible answers entries\n const possibleAnswers = Object.entries(questionPossibleAnswers);\n return possibleAnswers.reduce(\n (acc, entry) => {\n // iterating each possible answer (main + alternates)\n const possibleAnswerKey = entry[0];\n const possibleAnswer = entry[1] || {};\n let { marks } = possibleAnswer;\n if (!marks || !marks.length) {\n return acc;\n }\n // returns array of marks, each having 'correctness' property\n const correctedAnswer = getAnswerCorrected({ sessionAnswers, marks });\n const correctMarks = correctedAnswer.filter((answer) => answer.correctness === 'correct');\n // filter out missing objects because they do not affect the calculation of the score\n // only correct and incorrect are needed\n const scoredCorrectedAnswer = correctedAnswer.filter((answer) => answer.correctness !== 'missing');\n const maxScore = marks.length;\n let score = correctMarks.length;\n // if extra placements\n if (scoredCorrectedAnswer.length > maxScore) {\n score -= scoredCorrectedAnswer.length - maxScore;\n }\n if (score < 0) {\n score = 0;\n }\n if (score / maxScore > acc.bestScore || !acc.foundOneSolution) {\n acc.bestScore = Math.floor(score / maxScore);\n acc.bestScoreAnswerKey = possibleAnswerKey;\n acc.answersCorrected = correctedAnswer;\n acc.foundOneSolution = true;\n }\n return acc;\n },\n {\n bestScore: 0,\n bestScoreAnswerKey: null,\n // initially we just suppose all the answers are incorrect\n answersCorrected: cloneDeep(sessionAnswers).map((answer) => ({ ...answer, correctness: 'incorrect' })),\n foundOneSolution: false,\n },\n );\n};\n\n/*\n * Constant normalize\n * @param {Object} question - question object\n * */\nexport const normalize = (question) => ({ ...defaults, ...question });\n\n/*\n * Function to set model\n * @param {Object} question - question object\n * @param {Object} session - session object\n * @param {Object} env - env object\n * */\nexport function model(question, session, env) {\n return new Promise((resolve) => {\n const normalizedQuestion = normalize(question);\n // ensure removing of invalid answers\n // need this if undo redo was last operation\n session.answer = removeInvalidAnswers(session.answer);\n // console.log('normalizedQuestion', normalizedQuestion);\n const { defaultTool, extraCSSRules, prompt, promptEnabled, graph, answers, toolbarTools, ...questionProps } =\n normalizedQuestion || {};\n let { arrows } = normalizedQuestion;\n const { mode, role } = env || {};\n\n // This is used for offering support for old models which have the property arrows: boolean\n // Same thing is set in authoring : packages/graphing/configure/src/configure.jsx - componentDidMount\n if (typeof arrows === 'boolean') {\n if (arrows) {\n arrows = {\n left: true,\n right: true,\n up: true,\n down: true,\n };\n } else {\n arrows = {\n left: false,\n right: false,\n up: false,\n down: false,\n };\n }\n }\n\n const base = {\n ...questionProps,\n answers,\n arrows,\n defaultTool: 'line',\n disabled: env.mode !== 'gather',\n prompt: promptEnabled ? prompt : null,\n rationale: null,\n size: graph,\n showToggle:\n env.mode === 'evaluate' &&\n !isEmpty(answers) &&\n answers.correctAnswer &&\n answers.correctAnswer.marks &&\n !isEmpty(answers.correctAnswer.marks),\n teacherInstructions: null,\n toolbarTools,\n extraCSSRules,\n };\n\n if (role === 'instructor' && (mode === 'view' || mode === 'evaluate')) {\n const { rationale, rationaleEnabled, teacherInstructions, teacherInstructionsEnabled } = normalizedQuestion || {};\n\n base.rationale = rationaleEnabled ? rationale : null;\n base.teacherInstructions = teacherInstructionsEnabled ? teacherInstructions : null;\n }\n\n if (mode === 'evaluate') {\n if (\n !isEmpty(answers) &&\n answers.correctAnswer &&\n answers.correctAnswer.marks &&\n !isEmpty(answers.correctAnswer.marks)\n ) {\n const { answersCorrected, bestScoreAnswerKey, bestScore } = getBestAnswer(normalizedQuestion, session, env);\n // array of marks from session with 'correctness' property set\n base.answersCorrected = answersCorrected;\n base.correctResponse = bestScoreAnswerKey ? (answers[bestScoreAnswerKey] || {}).marks : [];\n base.showToggle = base.showToggle && bestScore !== 1;\n } else {\n base.answersCorrected = (session && session.answer) || [];\n base.correctResponse = [];\n }\n }\n\n log('base: ', base);\n resolve(base);\n });\n}\n\n/*\n * Function to check the outcome\n * @param {Object} question - question object\n * @param {Object} session - session object\n * @param {Object} env - env object\n * */\nexport function outcome(question, session, env = {}) {\n return new Promise((resolve) => {\n if (!session || isEmpty(session)) {\n resolve({ score: 0, empty: true });\n }\n if (\n env.mode !== 'evaluate' ||\n isEmpty(question.answers) ||\n (question.answers && question.answers.correctAnswer && isEmpty(question.answers.correctAnswer.marks))\n ) {\n resolve({ score: 0 });\n }\n const { bestScore } = getBestAnswer(question, session, env);\n resolve({ score: bestScore });\n });\n}\n\n/*\n * Constant to create correct response session\n * @param {Object} question - question object\n * @param {Object} env - env object\n * */\nexport const createCorrectResponseSession = (question, env) => {\n return new Promise((resolve) => {\n if (env.mode !== 'evaluate' && env.role === 'instructor') {\n const { answers } = question || {};\n let marks = [];\n if (answers && Object.values(answers)) {\n const correctAnswer = answers.correctAnswer || Object.values(answers)[0] || {};\n marks = correctAnswer.marks || [];\n }\n resolve({\n answer: marks,\n id: '1',\n });\n } else {\n resolve(null);\n }\n });\n};\n\n/*\n * Constant to validate model before saving item\n * @param {Object} model - model object\n * */\nexport const validate = (model = {}) => {\n const { answers, gssLineData } = model;\n const errors = {};\n const correctAnswerErrors = {};\n let found = false;\n if (gssLineData.numberOfLines === 1) {\n if (answers.correctAnswer.marks.length < 1) {\n found = true;\n correctAnswerErrors.correctAnswer = 'At least 1 line object should be defined.';\n } else if (answers.correctAnswer.marks.length === 1 && answers.correctAnswer.marks[0].building) {\n found = true;\n correctAnswerErrors.correctAnswer = '1 or more graph object should be correctly defined.';\n }\n } else {\n if (answers.correctAnswer.marks.length < 2) {\n found = true;\n correctAnswerErrors.correctAnswer = 'At least 2 line object should be defined.';\n } else if (answers.correctAnswer.marks.length === 2) {\n if (answers.correctAnswer.marks[0].building || answers.correctAnswer.marks[1].building) {\n found = true;\n correctAnswerErrors.correctAnswer = '1 or more graph object should be correctly defined.';\n }\n }\n }\n let polygon = answers.correctAnswer.marks.find((mark) => mark.type === 'polygon');\n if (!found && (!gssLineData.selectedTool === 'solutionSet' || !polygon)) {\n correctAnswerErrors.correctAnswer = 'Please select a solution set for the graphing solution set item.';\n }\n if (!isEmpty(correctAnswerErrors)) {\n errors.correctAnswerErrors = correctAnswerErrors;\n }\n return errors;\n};\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.sortedAnswers = exports.removeInvalidSegments = exports.removeInvalidAnswers = exports.removeDuplicateSegments = exports.equalSegment = exports.equalPolygon = exports.equalMarks = exports.equalLine = exports.constructSegmentsFromPoints = void 0;
|
|
7
|
+
var _lodashEs = require("lodash-es");
|
|
8
|
+
/*
|
|
9
|
+
* Constant to check equal segments
|
|
10
|
+
* @param {Object} segment1 - segment 1
|
|
11
|
+
* @param {Object} segment2 - segment 2
|
|
12
|
+
* */
|
|
13
|
+
const equalSegment = (segment1, segment2) => {
|
|
14
|
+
// A.from = B.from, A.to = B.to OR A.from = B.to, A.to = B.from
|
|
15
|
+
// x1 = x3 & y1 = y3 & x2 = x4 & y2 = y4
|
|
16
|
+
return (0, _lodashEs.isEqual)(segment1.from, segment2.from) && (0, _lodashEs.isEqual)(segment1.to, segment2.to) || (0, _lodashEs.isEqual)(segment1.to, segment2.from) && (0, _lodashEs.isEqual)(segment1.from, segment2.to);
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
// this function is implemented in configure as well
|
|
20
|
+
/*
|
|
21
|
+
* Constant to get sorted answers
|
|
22
|
+
* @param {Object} answers - answers
|
|
23
|
+
* */
|
|
24
|
+
exports.equalSegment = equalSegment;
|
|
25
|
+
const sortedAnswers = answers => Object.keys(answers || {}).sort().reduce((result, key) => {
|
|
26
|
+
if (key !== 'correctAnswer') {
|
|
27
|
+
result[key] = answers[key];
|
|
28
|
+
}
|
|
29
|
+
return result;
|
|
30
|
+
}, {});
|
|
31
|
+
|
|
32
|
+
/*
|
|
33
|
+
* Constant to return line equation coefficients
|
|
34
|
+
* @param {Object} line - line
|
|
35
|
+
* */
|
|
36
|
+
exports.sortedAnswers = sortedAnswers;
|
|
37
|
+
const returnLineEquationCoefficients = line => {
|
|
38
|
+
line = {
|
|
39
|
+
...line,
|
|
40
|
+
to: {
|
|
41
|
+
...line.to
|
|
42
|
+
},
|
|
43
|
+
from: {
|
|
44
|
+
...line.from
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
const xA = line.from.x;
|
|
48
|
+
const yA = line.from.y;
|
|
49
|
+
const xB = line.to.x;
|
|
50
|
+
const yB = line.to.y;
|
|
51
|
+
return {
|
|
52
|
+
a: yB - yA,
|
|
53
|
+
b: xA - xB,
|
|
54
|
+
c: xB * yA - xA * yB
|
|
55
|
+
};
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
/*
|
|
59
|
+
* Constant to get significant decimals
|
|
60
|
+
* @param {Number} number - number
|
|
61
|
+
* */
|
|
62
|
+
const getSignificantDecimals = number => Math.round(number * 10000) / 10000;
|
|
63
|
+
|
|
64
|
+
/*
|
|
65
|
+
* Constant to check equal lines
|
|
66
|
+
* @param {Object} line1 - line 1
|
|
67
|
+
* @param {Object} line2 - line 2
|
|
68
|
+
* */
|
|
69
|
+
const equalLine = (line1, line2) => {
|
|
70
|
+
// line equation: ax + by + c = 0
|
|
71
|
+
// 2 lines are equal if a1/a2 = b1/b2 = c1/c2, where a, b, c are the coefficients in line equation
|
|
72
|
+
// line equation knowing 2 points: (y - yA) / (yB - yA) = (x - xA) / (xB - xA)
|
|
73
|
+
// extending this equation, we get: x * (yB - yA) + y * (xA - xB) + (xB * yA - xA * yB) = 0
|
|
74
|
+
// where a = yB - yA; b = xA - xB; c = xB * yA - xA * yB
|
|
75
|
+
const {
|
|
76
|
+
a: a1,
|
|
77
|
+
b: b1,
|
|
78
|
+
c: c1
|
|
79
|
+
} = returnLineEquationCoefficients(line1);
|
|
80
|
+
const {
|
|
81
|
+
a: a2,
|
|
82
|
+
b: b2,
|
|
83
|
+
c: c2
|
|
84
|
+
} = returnLineEquationCoefficients(line2);
|
|
85
|
+
const proportions = [];
|
|
86
|
+
if (a2 !== 0) {
|
|
87
|
+
proportions.push(getSignificantDecimals(a1 / a2));
|
|
88
|
+
} else if (a1 !== a2) {
|
|
89
|
+
return false;
|
|
90
|
+
}
|
|
91
|
+
if (b2 !== 0) {
|
|
92
|
+
proportions.push(getSignificantDecimals(b1 / b2));
|
|
93
|
+
} else if (b1 !== b2) {
|
|
94
|
+
return false;
|
|
95
|
+
}
|
|
96
|
+
if (c2 !== 0) {
|
|
97
|
+
proportions.push(getSignificantDecimals(c1 / c2));
|
|
98
|
+
} else if (c1 !== c2) {
|
|
99
|
+
return false;
|
|
100
|
+
}
|
|
101
|
+
return (0, _lodashEs.uniq)(proportions).length === 1 && line1.fill === line2.fill;
|
|
102
|
+
// (y2 - y1)/(x2 - x1) = (y4 - y3)/(x4 - x3);
|
|
103
|
+
// return ((Math.abs((line1.to.y - line1.from.y) / (line1.to.x - line1.from.x))) === (Math.abs((line2.to.y - line2.from.y) / (line2.to.x - line2.from.x))));
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
/*
|
|
107
|
+
* Constant to construct segments from points
|
|
108
|
+
* @param {Array} points - points
|
|
109
|
+
* */
|
|
110
|
+
exports.equalLine = equalLine;
|
|
111
|
+
const constructSegmentsFromPoints = points => {
|
|
112
|
+
// takes the list of points that represent a polygon and transforms it into a list of segments; eg.:
|
|
113
|
+
// points: A, B, C, D => segments: AB, BC, CD, DA
|
|
114
|
+
return (points || []).map((point, index) => ({
|
|
115
|
+
from: point,
|
|
116
|
+
to: points[(index + 1) % points.length]
|
|
117
|
+
}));
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
/*
|
|
121
|
+
* Constant to remove duplicate segments
|
|
122
|
+
* @param {Array} segments - segments
|
|
123
|
+
* */
|
|
124
|
+
exports.constructSegmentsFromPoints = constructSegmentsFromPoints;
|
|
125
|
+
const removeDuplicateSegments = segments => {
|
|
126
|
+
segments = segments || [];
|
|
127
|
+
// removes segments that are duplicates; eg. These segments are the same, so one will be removed:
|
|
128
|
+
// segment1: from: { x: 1, y: 1 }, to: { x: 2, y: 1 }
|
|
129
|
+
// segment2: from: { x: 2, y: 1 }, to: { x: 1, y: 1 }
|
|
130
|
+
return (0, _lodashEs.uniqWith)(segments, (s1, s2) => equalSegment(s1, s2));
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
/*
|
|
134
|
+
* Constant to remove invalid segments
|
|
135
|
+
* @param {Array} segments - segments
|
|
136
|
+
* */
|
|
137
|
+
exports.removeDuplicateSegments = removeDuplicateSegments;
|
|
138
|
+
const removeInvalidSegments = segments => {
|
|
139
|
+
segments = segments || [];
|
|
140
|
+
// removes segments that start in a point and end in the same point (eg.: from: { x: 1, y: 1 }, to: { x: 1, y: 1 })
|
|
141
|
+
return segments.filter(segment => !(0, _lodashEs.isEqual)(segment.from, segment.to));
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
/*
|
|
145
|
+
* Constant to check equal polygons
|
|
146
|
+
* @param {Object} poly1 - polygon 1 points
|
|
147
|
+
* @param {Object} poly2 - polygon 2 points
|
|
148
|
+
* */
|
|
149
|
+
exports.removeInvalidSegments = removeInvalidSegments;
|
|
150
|
+
const equalPolygon = (poly1, poly2) => {
|
|
151
|
+
const {
|
|
152
|
+
points: points1
|
|
153
|
+
} = poly1;
|
|
154
|
+
const {
|
|
155
|
+
points: points2
|
|
156
|
+
} = poly2;
|
|
157
|
+
// generate segments
|
|
158
|
+
const segments1 = constructSegmentsFromPoints(points1);
|
|
159
|
+
const segments2 = constructSegmentsFromPoints(points2);
|
|
160
|
+
const segments1NoDuplicates = removeDuplicateSegments(removeInvalidSegments(segments1));
|
|
161
|
+
const segments2NoDuplicates = removeDuplicateSegments(removeInvalidSegments(segments2));
|
|
162
|
+
const differentSegments1 = (0, _lodashEs.differenceWith)(segments1NoDuplicates, segments2NoDuplicates, equalSegment);
|
|
163
|
+
const differentSegments2 = (0, _lodashEs.differenceWith)(segments2NoDuplicates, segments1NoDuplicates, equalSegment);
|
|
164
|
+
return (!differentSegments1 || !differentSegments1.length) && (!differentSegments2 || !differentSegments2.length);
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
/*
|
|
168
|
+
* Constant to compare equal marks
|
|
169
|
+
* */
|
|
170
|
+
exports.equalPolygon = equalPolygon;
|
|
171
|
+
const equalMarks = exports.equalMarks = {
|
|
172
|
+
line: (sessAnswer, mark) => equalLine(sessAnswer, mark),
|
|
173
|
+
polygon: (sessAnswer, poly) => equalPolygon(sessAnswer, poly)
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
/*
|
|
177
|
+
* Check if a point is correct and complete
|
|
178
|
+
* @param {Object} point - point object
|
|
179
|
+
* */
|
|
180
|
+
const completePoint = point => point && Number.isFinite(point.x) && Number.isFinite(point.y);
|
|
181
|
+
|
|
182
|
+
/*
|
|
183
|
+
* Check if a line is complete
|
|
184
|
+
* @param {Object} item - mark object
|
|
185
|
+
* */
|
|
186
|
+
const completeFromTo = item => item && completeMark.point(item.from) && completeMark.point(item.to);
|
|
187
|
+
|
|
188
|
+
/*
|
|
189
|
+
* Check if a point is correct and complete
|
|
190
|
+
* @param {Object} item - mark object
|
|
191
|
+
* */
|
|
192
|
+
const completePoints = item => item && item.points && item.points.length && (item.points.filter(point => completePoint(point)) || []).length === item.points.length;
|
|
193
|
+
|
|
194
|
+
/*
|
|
195
|
+
* Complete mark object for line and point
|
|
196
|
+
* */
|
|
197
|
+
const completeMark = {
|
|
198
|
+
point: completePoint,
|
|
199
|
+
line: completeFromTo,
|
|
200
|
+
polygon: completePoints
|
|
201
|
+
};
|
|
202
|
+
|
|
203
|
+
/*
|
|
204
|
+
* Function to remove invalid answers
|
|
205
|
+
* @param {Array} answers - answers array
|
|
206
|
+
* */
|
|
207
|
+
const removeInvalidAnswers = answers => answers ? (answers || []).filter(({
|
|
208
|
+
type,
|
|
209
|
+
...answer
|
|
210
|
+
}) => completeMark[type] ? completeMark[type](answer) : false) : [];
|
|
211
|
+
exports.removeInvalidAnswers = removeInvalidAnswers;
|
|
212
|
+
//# sourceMappingURL=utils.js.map
|