jclic 2.1.21 → 2.1.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/CHANGELOG.md +13 -0
- package/dist/jclic-node.js +9 -8
- package/dist/jclic-node.js.map +1 -1
- package/dist/jclic.min.js +2 -2
- package/dist/jclic.min.js.map +1 -1
- package/package.json +4 -4
- package/src/GlobalData.js +1 -1
- package/src/JClicPlayer.js +2 -2
- package/src/bags/MediaBag.js +6 -5
- package/dist/1078.jclic-node.js +0 -282
- package/dist/1078.jclic-node.js.map +0 -1
- package/dist/1196.jclic-node.js +0 -808
- package/dist/1196.jclic-node.js.map +0 -1
- package/dist/1253.jclic-node.js +0 -1432
- package/dist/1253.jclic-node.js.map +0 -1
- package/dist/13.jclic-node.js +0 -103
- package/dist/13.jclic-node.js.map +0 -1
- package/dist/1567.jclic-node.js +0 -2313
- package/dist/1567.jclic-node.js.map +0 -1
- package/dist/1588.jclic-node.js +0 -602
- package/dist/1588.jclic-node.js.map +0 -1
- package/dist/1725.jclic-node.js +0 -836
- package/dist/1725.jclic-node.js.map +0 -1
- package/dist/1731.jclic-node.js +0 -438
- package/dist/1731.jclic-node.js.map +0 -1
- package/dist/1842.jclic-node.js +0 -651
- package/dist/1842.jclic-node.js.map +0 -1
- package/dist/2160.jclic-node.js +0 -1016
- package/dist/2160.jclic-node.js.map +0 -1
- package/dist/222.jclic-node.js +0 -129
- package/dist/222.jclic-node.js.map +0 -1
- package/dist/2316.jclic-node.js +0 -949
- package/dist/2316.jclic-node.js.map +0 -1
- package/dist/2355.jclic-node.js +0 -371
- package/dist/2355.jclic-node.js.map +0 -1
- package/dist/2366.jclic-node.js +0 -431
- package/dist/2366.jclic-node.js.map +0 -1
- package/dist/2379.jclic-node.js +0 -202
- package/dist/2379.jclic-node.js.map +0 -1
- package/dist/2437.jclic-node.js +0 -450
- package/dist/2437.jclic-node.js.map +0 -1
- package/dist/2531.jclic-node.js +0 -869
- package/dist/2531.jclic-node.js.map +0 -1
- package/dist/2608.jclic-node.js +0 -160
- package/dist/2608.jclic-node.js.map +0 -1
- package/dist/2715.jclic-node.js +0 -554
- package/dist/2715.jclic-node.js.map +0 -1
- package/dist/277.jclic-node.js +0 -22
- package/dist/277.jclic-node.js.map +0 -1
- package/dist/2921.jclic-node.js +0 -660
- package/dist/2921.jclic-node.js.map +0 -1
- package/dist/2952.jclic-node.js +0 -101
- package/dist/2952.jclic-node.js.map +0 -1
- package/dist/3018.jclic-node.js +0 -421
- package/dist/3018.jclic-node.js.map +0 -1
- package/dist/3019.jclic-node.js +0 -682
- package/dist/3019.jclic-node.js.map +0 -1
- package/dist/3231.jclic-node.js +0 -274
- package/dist/3231.jclic-node.js.map +0 -1
- package/dist/331.jclic-node.js +0 -115
- package/dist/331.jclic-node.js.map +0 -1
- package/dist/3391.jclic-node.js +0 -276
- package/dist/3391.jclic-node.js.map +0 -1
- package/dist/3502.jclic-node.js +0 -671
- package/dist/3502.jclic-node.js.map +0 -1
- package/dist/3653.jclic-node.js +0 -982
- package/dist/3653.jclic-node.js.map +0 -1
- package/dist/371.jclic.min.js +0 -2
- package/dist/371.jclic.min.js.map +0 -1
- package/dist/3856.jclic-node.js +0 -575
- package/dist/3856.jclic-node.js.map +0 -1
- package/dist/4112.jclic-node.js +0 -659
- package/dist/4112.jclic-node.js.map +0 -1
- package/dist/4123.jclic-node.js +0 -910
- package/dist/4123.jclic-node.js.map +0 -1
- package/dist/427.jclic-node.js +0 -894
- package/dist/427.jclic-node.js.map +0 -1
- package/dist/4483.jclic-node.js +0 -327
- package/dist/4483.jclic-node.js.map +0 -1
- package/dist/4548.jclic-node.js +0 -1078
- package/dist/4548.jclic-node.js.map +0 -1
- package/dist/466.jclic-node.js +0 -99
- package/dist/466.jclic-node.js.map +0 -1
- package/dist/485.jclic-node.js +0 -783
- package/dist/485.jclic-node.js.map +0 -1
- package/dist/4921.jclic-node.js +0 -500
- package/dist/4921.jclic-node.js.map +0 -1
- package/dist/5091.jclic-node.js +0 -239
- package/dist/5091.jclic-node.js.map +0 -1
- package/dist/520.jclic-node.js +0 -550
- package/dist/520.jclic-node.js.map +0 -1
- package/dist/5312.jclic-node.js +0 -1126
- package/dist/5312.jclic-node.js.map +0 -1
- package/dist/5338.jclic-node.js +0 -212
- package/dist/5338.jclic-node.js.map +0 -1
- package/dist/5344.jclic-node.js +0 -229
- package/dist/5344.jclic-node.js.map +0 -1
- package/dist/5550.jclic-node.js +0 -238
- package/dist/5550.jclic-node.js.map +0 -1
- package/dist/5626.jclic-node.js +0 -614
- package/dist/5626.jclic-node.js.map +0 -1
- package/dist/5977.jclic-node.js +0 -1081
- package/dist/5977.jclic-node.js.map +0 -1
- package/dist/6148.jclic-node.js +0 -345
- package/dist/6148.jclic-node.js.map +0 -1
- package/dist/6176.jclic-node.js +0 -481
- package/dist/6176.jclic-node.js.map +0 -1
- package/dist/6221.jclic-node.js +0 -1072
- package/dist/6221.jclic-node.js.map +0 -1
- package/dist/6238.jclic-node.js +0 -718
- package/dist/6238.jclic-node.js.map +0 -1
- package/dist/6454.jclic-node.js +0 -1413
- package/dist/6454.jclic-node.js.map +0 -1
- package/dist/6565.jclic-node.js +0 -294
- package/dist/6565.jclic-node.js.map +0 -1
- package/dist/6579.jclic-node.js +0 -719
- package/dist/6579.jclic-node.js.map +0 -1
- package/dist/6715.jclic-node.js +0 -148
- package/dist/6715.jclic-node.js.map +0 -1
- package/dist/6777.jclic-node.js +0 -171
- package/dist/6777.jclic-node.js.map +0 -1
- package/dist/6782.jclic-node.js +0 -1611
- package/dist/6782.jclic-node.js.map +0 -1
- package/dist/6847.jclic-node.js +0 -601
- package/dist/6847.jclic-node.js.map +0 -1
- package/dist/6856.jclic-node.js +0 -252
- package/dist/6856.jclic-node.js.map +0 -1
- package/dist/696.jclic-node.js +0 -1821
- package/dist/696.jclic-node.js.map +0 -1
- package/dist/698.jclic-node.js +0 -583
- package/dist/698.jclic-node.js.map +0 -1
- package/dist/704.jclic-node.js +0 -80
- package/dist/704.jclic-node.js.map +0 -1
- package/dist/7046.jclic-node.js +0 -735
- package/dist/7046.jclic-node.js.map +0 -1
- package/dist/7220.jclic-node.js +0 -156
- package/dist/7220.jclic-node.js.map +0 -1
- package/dist/7257.jclic-node.js +0 -931
- package/dist/7257.jclic-node.js.map +0 -1
- package/dist/743.jclic-node.js +0 -583
- package/dist/743.jclic-node.js.map +0 -1
- package/dist/757.jclic-node.js +0 -1072
- package/dist/757.jclic-node.js.map +0 -1
- package/dist/7781.jclic-node.js +0 -202
- package/dist/7781.jclic-node.js.map +0 -1
- package/dist/7912.jclic-node.js +0 -2103
- package/dist/7912.jclic-node.js.map +0 -1
- package/dist/827.jclic-node.js +0 -708
- package/dist/827.jclic-node.js.map +0 -1
- package/dist/8276.jclic-node.js +0 -409
- package/dist/8276.jclic-node.js.map +0 -1
- package/dist/8322.jclic-node.js +0 -498
- package/dist/8322.jclic-node.js.map +0 -1
- package/dist/8641.jclic-node.js +0 -360
- package/dist/8641.jclic-node.js.map +0 -1
- package/dist/8837.jclic-node.js +0 -651
- package/dist/8837.jclic-node.js.map +0 -1
- package/dist/8895.jclic-node.js +0 -151
- package/dist/8895.jclic-node.js.map +0 -1
- package/dist/9072.jclic-node.js +0 -1285
- package/dist/9072.jclic-node.js.map +0 -1
- package/dist/9078.jclic-node.js +0 -935
- package/dist/9078.jclic-node.js.map +0 -1
- package/dist/9103.jclic-node.js +0 -718
- package/dist/9103.jclic-node.js.map +0 -1
- package/dist/9359.jclic-node.js +0 -145
- package/dist/9359.jclic-node.js.map +0 -1
- package/dist/9409.jclic-node.js +0 -921
- package/dist/9409.jclic-node.js.map +0 -1
- package/dist/9513.jclic-node.js +0 -720
- package/dist/9513.jclic-node.js.map +0 -1
- package/dist/9704.jclic-node.js +0 -81
- package/dist/9704.jclic-node.js.map +0 -1
- package/dist/9950.jclic-node.js +0 -827
- package/dist/9950.jclic-node.js.map +0 -1
package/dist/2715.jclic-node.js
DELETED
|
@@ -1,554 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
exports.id = 2715;
|
|
3
|
-
exports.ids = [2715];
|
|
4
|
-
exports.modules = {
|
|
5
|
-
|
|
6
|
-
/***/ 2715:
|
|
7
|
-
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
8
|
-
|
|
9
|
-
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
10
|
-
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
|
|
11
|
-
/* harmony export */ });
|
|
12
|
-
/* unused harmony exports Evaluator, BasicEvaluator, ComplexEvaluator */
|
|
13
|
-
/* harmony import */ var _Utils_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1253);
|
|
14
|
-
/**
|
|
15
|
-
* File : activities/text/Evaluator.js
|
|
16
|
-
* Created : 14/04/2015
|
|
17
|
-
* By : Francesc Busquets <francesc@gmail.com>
|
|
18
|
-
*
|
|
19
|
-
* JClic.js
|
|
20
|
-
* An HTML5 player of JClic activities
|
|
21
|
-
* https://projectestac.github.io/jclic.js
|
|
22
|
-
*
|
|
23
|
-
* @source https://github.com/projectestac/jclic.js
|
|
24
|
-
*
|
|
25
|
-
* @license EUPL-1.2
|
|
26
|
-
* @licstart
|
|
27
|
-
* (c) 2000-2020 Educational Telematic Network of Catalonia (XTEC)
|
|
28
|
-
*
|
|
29
|
-
* Licensed under the EUPL, Version 1.1 or -as soon they will be approved by
|
|
30
|
-
* the European Commission- subsequent versions of the EUPL (the "Licence");
|
|
31
|
-
* You may not use this work except in compliance with the Licence.
|
|
32
|
-
*
|
|
33
|
-
* You may obtain a copy of the Licence at:
|
|
34
|
-
* https://joinup.ec.europa.eu/software/page/eupl
|
|
35
|
-
*
|
|
36
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
37
|
-
* distributed under the Licence is distributed on an "AS IS" basis, WITHOUT
|
|
38
|
-
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
39
|
-
* Licence for the specific language governing permissions and limitations
|
|
40
|
-
* under the Licence.
|
|
41
|
-
* @licend
|
|
42
|
-
* @module
|
|
43
|
-
*/
|
|
44
|
-
|
|
45
|
-
/* global window */
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* This class and its derivatives {@link module:activities/text/Evaluator.BasicEvaluator BasicEvaluator} and
|
|
51
|
-
* {@link module:activities/text/Evaluator.ComplexEvaluator ComplexEvaluator} are used to evaluate the answers written by the final users
|
|
52
|
-
* in text activities.
|
|
53
|
-
*/
|
|
54
|
-
class Evaluator {
|
|
55
|
-
/**
|
|
56
|
-
* Evaluator constructor
|
|
57
|
-
* @param {string} className - The class name of this evaluator.
|
|
58
|
-
*/
|
|
59
|
-
constructor(className) {
|
|
60
|
-
this.className = className;
|
|
61
|
-
this.collator = (window.Intl && window.Intl.Collator) ?
|
|
62
|
-
new window.Intl.Collator() :
|
|
63
|
-
{ compare: (a, b) => this.checkCase ? a === b : a.toUpperCase() === b.toUpperCase() };
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* Factory constructor that returns a specific type of {@link module:activities/text/Evaluator.Evaluator Evaluator} based on the `class`
|
|
68
|
-
* attribute declared in the $xml element.
|
|
69
|
-
* @param {external:jQuery} $xml - The XML element to be parsed.
|
|
70
|
-
* @returns {module:activities/text/Evaluator.Evaluator}
|
|
71
|
-
*/
|
|
72
|
-
static getEvaluator($xml) {
|
|
73
|
-
let ev = null;
|
|
74
|
-
if ($xml) {
|
|
75
|
-
const className = $xml.attr('class');
|
|
76
|
-
const cl = Evaluator.CLASSES[className];
|
|
77
|
-
if (cl) {
|
|
78
|
-
ev = new cl(className);
|
|
79
|
-
ev.setProperties($xml);
|
|
80
|
-
} else
|
|
81
|
-
(0,_Utils_js__WEBPACK_IMPORTED_MODULE_0__/* .log */ .Rm)('error', `Unknown evaluator class: "${className}"`);
|
|
82
|
-
}
|
|
83
|
-
return ev;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
/**
|
|
87
|
-
* Loads the object settings from a specific JQuery XML element
|
|
88
|
-
* @param {external:jQuery} $xml - The jQuery XML element to parse
|
|
89
|
-
*/
|
|
90
|
-
setProperties($xml) {
|
|
91
|
-
(0,_Utils_js__WEBPACK_IMPORTED_MODULE_0__/* .attrForEach */ .GM)($xml.get(0).attributes, (name, value) => {
|
|
92
|
-
switch (name) {
|
|
93
|
-
case 'class':
|
|
94
|
-
this.className = value;
|
|
95
|
-
break;
|
|
96
|
-
case 'checkCase':
|
|
97
|
-
case 'checkAccents':
|
|
98
|
-
case 'checkPunctuation':
|
|
99
|
-
case 'checkDoubleSpaces':
|
|
100
|
-
case 'detail':
|
|
101
|
-
this[name] = (0,_Utils_js__WEBPACK_IMPORTED_MODULE_0__/* .getBoolean */ .pW)(value);
|
|
102
|
-
break;
|
|
103
|
-
case 'checkSteps':
|
|
104
|
-
case 'checkScope':
|
|
105
|
-
this[name] = Number(value);
|
|
106
|
-
break;
|
|
107
|
-
}
|
|
108
|
-
});
|
|
109
|
-
return this;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
/**
|
|
113
|
-
* Builds a new Evaluator, based on the properties specified in a data object
|
|
114
|
-
* @param {object} data - The data object to be parsed
|
|
115
|
-
* @returns {module:activities/text/Evaluator.Evaluator}
|
|
116
|
-
*/
|
|
117
|
-
static factory(data) {
|
|
118
|
-
const cl = Evaluator.CLASSES[data.className];
|
|
119
|
-
if (cl) {
|
|
120
|
-
const result = new cl(data.className);
|
|
121
|
-
return (0,_Utils_js__WEBPACK_IMPORTED_MODULE_0__/* .setAttr */ .ob)(result, data, [
|
|
122
|
-
'className',
|
|
123
|
-
'checkCase', 'checkAccents', 'checkPunctuation', 'checkDoubleSpaces', 'detail',
|
|
124
|
-
'checkSteps', 'checkScope',
|
|
125
|
-
]);
|
|
126
|
-
}
|
|
127
|
-
return null;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
/**
|
|
131
|
-
* Gets a object with the basic attributes needed to rebuild this instance excluding functions,
|
|
132
|
-
* parent references, constants and also attributes retaining the default value.
|
|
133
|
-
* The resulting object is commonly usued to serialize elements in JSON format.
|
|
134
|
-
* @returns {object} - The resulting object, with minimal attrributes
|
|
135
|
-
*/
|
|
136
|
-
getAttributes() {
|
|
137
|
-
return (0,_Utils_js__WEBPACK_IMPORTED_MODULE_0__/* .getAttr */ .iu)(this, [
|
|
138
|
-
'className',
|
|
139
|
-
'checkCase', 'checkAccents', 'checkPunctuation', 'checkDoubleSpaces', 'detail',
|
|
140
|
-
'checkSteps', 'checkScope',
|
|
141
|
-
]);
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
/**
|
|
145
|
-
* Initializes this evaluator
|
|
146
|
-
* @param {string[]} _locales - An array of valid locales, to be used by Intl.Collator
|
|
147
|
-
*/
|
|
148
|
-
init(_locales) {
|
|
149
|
-
this.initiated = true;
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
/**
|
|
153
|
-
* Checks the given text against a set of valid matches
|
|
154
|
-
* @param {string} text - The text to be checked
|
|
155
|
-
* @param {string|string[]} match - The valid expression or expressions with which to compare.
|
|
156
|
-
* @returns {boolean} - `true` if the checked expression is valid, `false` otherwise.
|
|
157
|
-
*/
|
|
158
|
-
checkText(text, match) {
|
|
159
|
-
if (match instanceof Array)
|
|
160
|
-
return match.some(m => this._checkText(text, m));
|
|
161
|
-
else if (match)
|
|
162
|
-
return this._checkText(text, match);
|
|
163
|
-
else
|
|
164
|
-
return false;
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
/**
|
|
168
|
-
* Abstract method to be implemented in subclasses.
|
|
169
|
-
* Performs the validation of a string against a single match.
|
|
170
|
-
* @param {string} _text - The text to be checked
|
|
171
|
-
* @param {string} _match - A valid expression with which to compare.
|
|
172
|
-
* @returns {boolean} - `true` when the two expressions can be considered equivalent.
|
|
173
|
-
*/
|
|
174
|
-
_checkText(_text, _match) {
|
|
175
|
-
return false;
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
/**
|
|
179
|
-
* Evaluates the given text against a set of valid matches, returning an array of flags useful
|
|
180
|
-
* to indicate where the mistakes are located.
|
|
181
|
-
* @param {string} text - The text to be checked
|
|
182
|
-
* @param {string|string[]} match - The valid expression or expressions with which to compare.
|
|
183
|
-
* @returns {number[]} - An array of flags (one number for character) indicating whether each
|
|
184
|
-
* position is erroneous or ok.
|
|
185
|
-
*/
|
|
186
|
-
evalText(text, match) {
|
|
187
|
-
if (!(match instanceof Array))
|
|
188
|
-
match = [match];
|
|
189
|
-
return this._evalText(text, match);
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
/**
|
|
193
|
-
* Abstract method to be implemented in subclasses.
|
|
194
|
-
* Performs the evaluation of a string against an array of valid matches, returning an array of
|
|
195
|
-
* flags useful to indicate where the mistakes are located.
|
|
196
|
-
* @param {string} _text - The text to be checked
|
|
197
|
-
* @param {string} _match - A valid expression with which to compare.
|
|
198
|
-
* @returns {number[]} - An array of flags (one number for character) indicating whether each
|
|
199
|
-
* position is erroneous or OK.
|
|
200
|
-
*/
|
|
201
|
-
_evalText(_text, _match) {
|
|
202
|
-
return [];
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
/**
|
|
206
|
-
* Checks if the given array of flags (usually returned by `evalText`) can be considered as a
|
|
207
|
-
* valid or erroneous answer.
|
|
208
|
-
* @param {number[]} flags
|
|
209
|
-
* @returns {boolean} - `true` when there is at least one flag and all flags are 0 (meaning no error).
|
|
210
|
-
*/
|
|
211
|
-
isOk(flags) {
|
|
212
|
-
return flags && flags.length > 0 && !flags.some(f => f !== 0);
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
Object.assign(Evaluator.prototype, {
|
|
217
|
-
/**
|
|
218
|
-
* The type of evaluator.
|
|
219
|
-
* @name module:activities/text/Evaluator.Evaluator#className
|
|
220
|
-
* @type {string} */
|
|
221
|
-
className: null,
|
|
222
|
-
/**
|
|
223
|
-
* Whether this evaluator has been initialized or not.
|
|
224
|
-
* @name module:activities/text/Evaluator.Evaluator#initiated
|
|
225
|
-
* @type {boolean} */
|
|
226
|
-
initiated: false,
|
|
227
|
-
/**
|
|
228
|
-
* The Intl.Collator object used to compare strings, when available.
|
|
229
|
-
* @name module:activities/text/Evaluator.Evaluator#collator
|
|
230
|
-
* @type {external:Collator} */
|
|
231
|
-
collator: null,
|
|
232
|
-
/**
|
|
233
|
-
* Whether uppercase and lowercase expressions must be considered equivalent or not.
|
|
234
|
-
* @name module:activities/text/Evaluator.Evaluator#checkcase
|
|
235
|
-
* @type {boolean} */
|
|
236
|
-
checkCase: false,
|
|
237
|
-
});
|
|
238
|
-
|
|
239
|
-
/**
|
|
240
|
-
* A basic evaluator that just compares texts, without looking for possible coincidences of text
|
|
241
|
-
* fragments once erroneous characters removed.
|
|
242
|
-
* @extends module:activities/text/Evaluator.Evaluator
|
|
243
|
-
*/
|
|
244
|
-
class BasicEvaluator extends Evaluator {
|
|
245
|
-
/**
|
|
246
|
-
* BasicEvaluator constructor
|
|
247
|
-
* @param {string} className - The class name of this evaluator.
|
|
248
|
-
*/
|
|
249
|
-
constructor(className) {
|
|
250
|
-
super(className);
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
/**
|
|
254
|
-
* Initializes the {@link module:activities/text/Evaluator.Evaluator#collator collator}.
|
|
255
|
-
* @override
|
|
256
|
-
* @param {string[]} locales - An array of valid locales to be used by the Inlt.Collator object
|
|
257
|
-
*/
|
|
258
|
-
init(locales) {
|
|
259
|
-
// Call `init` method on ancestor
|
|
260
|
-
super.init([locales]);
|
|
261
|
-
|
|
262
|
-
// Get canonical locales
|
|
263
|
-
if (window.Intl && window.Intl.Collator) {
|
|
264
|
-
this.collator = new window.Intl.Collator(locales, {
|
|
265
|
-
sensitivity: this.checkAccents ? this.checkCase ? 'case' : 'accent' : 'base',
|
|
266
|
-
ignorePunctuation: !this.checkPunctuation
|
|
267
|
-
});
|
|
268
|
-
}
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
/**
|
|
272
|
-
* Performs the validation of a string against a single match.
|
|
273
|
-
* @override
|
|
274
|
-
* @param {string} text - The text to be checked
|
|
275
|
-
* @param {string} match - A valid expression with which to compare.
|
|
276
|
-
* @returns {boolean} - `true` when the two expressions can be considered equivalent.
|
|
277
|
-
*/
|
|
278
|
-
_checkText(text, match) {
|
|
279
|
-
return this.collator.compare(this.getClearedText(text), this.getClearedText(match)) === 0;
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
/**
|
|
283
|
-
* Performs the evaluation of a string against an array of valid matches, returning an array of
|
|
284
|
-
* flags useful to indicate where the mistakes are located.
|
|
285
|
-
* In BasicEvaluator, all characters are just marked as 1 (error) or 0 (OK). See
|
|
286
|
-
* {@link module:activities/text/Evaluator.ComplexEvaluator ComplexEvaluator} for more detailed analysis of answers.
|
|
287
|
-
* @override
|
|
288
|
-
* @param {string} text - The text to be checked
|
|
289
|
-
* @param {string} match - A valid expression with which to compare.
|
|
290
|
-
* @returns {number[]} - An array of flags (one number for character) indicating whether each
|
|
291
|
-
* position is erroneous or OK.
|
|
292
|
-
*/
|
|
293
|
-
_evalText(text, match) {
|
|
294
|
-
return Array(text.length).fill(this._checkText(text, match[0]) ? 0 : 1);
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
/**
|
|
298
|
-
* Removes double spaces and erroneous characters from a given text expression.
|
|
299
|
-
* @param {string} src - The text to be processed.
|
|
300
|
-
* @param {boolean[]} skipped - An array of boolean indicating which characters should be removed
|
|
301
|
-
* from the string.
|
|
302
|
-
* @returns {string}
|
|
303
|
-
*/
|
|
304
|
-
getClearedText(src, skipped) {
|
|
305
|
-
if (this.checkPunctuation && this.checkDoubleSpaces)
|
|
306
|
-
return src;
|
|
307
|
-
|
|
308
|
-
if (!skipped)
|
|
309
|
-
skipped = Array(src.length).fill(false);
|
|
310
|
-
|
|
311
|
-
let sb = '';
|
|
312
|
-
for (let i = 0, wasSpace = false; i < src.length; i++) {
|
|
313
|
-
const ch = src.charAt(i);
|
|
314
|
-
if (this.PUNCTUATION.indexOf(ch) >= 0 && !this.checkPunctuation) {
|
|
315
|
-
if (!wasSpace)
|
|
316
|
-
sb += ' ';
|
|
317
|
-
else
|
|
318
|
-
skipped[i] = true;
|
|
319
|
-
wasSpace = true;
|
|
320
|
-
} else if (ch === ' ') {
|
|
321
|
-
if (this.checkDoubleSpaces || !wasSpace)
|
|
322
|
-
sb += ch;
|
|
323
|
-
else
|
|
324
|
-
skipped[i] = true;
|
|
325
|
-
wasSpace = true;
|
|
326
|
-
} else {
|
|
327
|
-
wasSpace = false;
|
|
328
|
-
sb += ch;
|
|
329
|
-
}
|
|
330
|
-
}
|
|
331
|
-
return sb;
|
|
332
|
-
}
|
|
333
|
-
}
|
|
334
|
-
|
|
335
|
-
Object.assign(BasicEvaluator.prototype, {
|
|
336
|
-
/**
|
|
337
|
-
* Whether accented letters must be considered equivalent or not.
|
|
338
|
-
* @name module:activities/text/Evaluator.BasicEvaluator#checkAccents
|
|
339
|
-
* @type {boolean} */
|
|
340
|
-
checkAccents: true,
|
|
341
|
-
/**
|
|
342
|
-
* Whether to check or not dots, commas and other punctuation marks when comparing texts.
|
|
343
|
-
* @name module:activities/text/Evaluator.BasicEvaluator#checkPunctuation
|
|
344
|
-
* @type {boolean} */
|
|
345
|
-
checkPunctuation: true,
|
|
346
|
-
/**
|
|
347
|
-
* Whether to check or not the extra spaces added between words.
|
|
348
|
-
* @name module:activities/text/Evaluator.BasicEvaluator#checkDoubleSpaces
|
|
349
|
-
* @type {boolean} */
|
|
350
|
-
checkDoubleSpaces: false,
|
|
351
|
-
/**
|
|
352
|
-
* String containing all the characters considered as punctuation marks (currently ".,;:")
|
|
353
|
-
* @name module:activities/text/Evaluator.BasicEvaluator#PUNCTUATION
|
|
354
|
-
* @type {string} */
|
|
355
|
-
PUNCTUATION: '.,;:',
|
|
356
|
-
});
|
|
357
|
-
|
|
358
|
-
/**
|
|
359
|
-
* ComplexEvaluator acts like {@link module:activities/text/Evaluator.BasicEvaluator BasicEvaluator}, but providing feedback about
|
|
360
|
-
* the location of mistakes on the user's answer.
|
|
361
|
-
* @extends module:activities/text/Evaluator.BasicEvaluator
|
|
362
|
-
*/
|
|
363
|
-
class ComplexEvaluator extends BasicEvaluator {
|
|
364
|
-
/**
|
|
365
|
-
* ComplexEvaluator constructor
|
|
366
|
-
* @param {string} className - The class name of this evaluator.
|
|
367
|
-
*/
|
|
368
|
-
constructor(className) {
|
|
369
|
-
super(className);
|
|
370
|
-
}
|
|
371
|
-
|
|
372
|
-
/**
|
|
373
|
-
* Performs the evaluation of a string against an array of valid matches, returning an array of
|
|
374
|
-
* flags useful to indicate where the mistakes are located.
|
|
375
|
-
* In BasicEvaluator, all characters are just marked as 1 (error) or 0 (OK). See
|
|
376
|
-
* {@link module:activities/text/Evaluator.ComplexEvaluator ComplexEvaluator} for more detailed analysis of answers.
|
|
377
|
-
* @override
|
|
378
|
-
* @param {string} text - The text to be checked
|
|
379
|
-
* @param {string} match - A valid expression with which to compare.
|
|
380
|
-
* @returns {number[]} - An array of flags (one number for character) indicating whether each
|
|
381
|
-
* position is erroneous or OK.
|
|
382
|
-
*/
|
|
383
|
-
_evalText(text, match) {
|
|
384
|
-
|
|
385
|
-
if (!this.detail)
|
|
386
|
-
return super._evalText(text, match);
|
|
387
|
-
|
|
388
|
-
const
|
|
389
|
-
skipped = Array(text.length).fill(false),
|
|
390
|
-
sText = this.getClearedText(text, skipped),
|
|
391
|
-
numChecks = Array(match.length),
|
|
392
|
-
flags = Array(match.length),
|
|
393
|
-
returnFlags = Array(text.length);
|
|
394
|
-
let
|
|
395
|
-
maxCheck = -1,
|
|
396
|
-
maxCheckIndex = -1;
|
|
397
|
-
|
|
398
|
-
for (let i = 0; i < match.length; i++) {
|
|
399
|
-
flags[i] = Array(text.length).fill(0);
|
|
400
|
-
const ok = this.compareSegment(sText, sText.length, match[i], match[i].length, flags[i], false);
|
|
401
|
-
numChecks[i] = this.countFlagsOk(flags[i]);
|
|
402
|
-
if (ok) {
|
|
403
|
-
maxCheckIndex = i;
|
|
404
|
-
maxCheck = numChecks[i];
|
|
405
|
-
}
|
|
406
|
-
}
|
|
407
|
-
|
|
408
|
-
if (maxCheckIndex === -1) {
|
|
409
|
-
for (let i = 0; i < match.length; i++) {
|
|
410
|
-
if (numChecks[i] > maxCheck) {
|
|
411
|
-
maxCheck = numChecks[i];
|
|
412
|
-
maxCheckIndex = i;
|
|
413
|
-
}
|
|
414
|
-
}
|
|
415
|
-
}
|
|
416
|
-
|
|
417
|
-
for (let i = 0, k = 0; i < text.length; i++)
|
|
418
|
-
returnFlags[i] = skipped[i] ? 0 : flags[maxCheckIndex][k++];
|
|
419
|
-
|
|
420
|
-
return returnFlags;
|
|
421
|
-
}
|
|
422
|
-
|
|
423
|
-
/**
|
|
424
|
-
* Counts the number of flags on the provided array that are zero.
|
|
425
|
-
* @param {number[]} flags
|
|
426
|
-
* @returns {number}
|
|
427
|
-
*/
|
|
428
|
-
countFlagsOk(flags) {
|
|
429
|
-
return flags.reduce((n, v) => v == 0 ? ++n : n, 0);
|
|
430
|
-
}
|
|
431
|
-
|
|
432
|
-
/**
|
|
433
|
-
* Compares two segments of text.
|
|
434
|
-
* This function should make recursive calls.
|
|
435
|
-
* @param {string} src - Text to be compared
|
|
436
|
-
* @param {number} ls - Offset in `src` where to start the comparison
|
|
437
|
-
* @param {string} ok - Text to match against.
|
|
438
|
-
* @param {number} lok - Offset in `ok` where to start the comparison.
|
|
439
|
-
* @param {number[]} attr - Array of integers that will be filled with information about the
|
|
440
|
-
* validity or error of each character in `src`.
|
|
441
|
-
* @param {boolean} iterate - When `true`, the segment will be iterated looking for other
|
|
442
|
-
* coincident fragments.
|
|
443
|
-
* @returns {boolean} - `true` if the comparison was valid.
|
|
444
|
-
*/
|
|
445
|
-
compareSegment(src, ls, ok, lok, attr, iterate) {
|
|
446
|
-
let
|
|
447
|
-
is = 0,
|
|
448
|
-
iok = 0,
|
|
449
|
-
lastIs = 0,
|
|
450
|
-
lastiok = true,
|
|
451
|
-
result = true,
|
|
452
|
-
chs = '',
|
|
453
|
-
chok = '';
|
|
454
|
-
|
|
455
|
-
if (ls === 0 || lok === 0 || src === null || ok === null)
|
|
456
|
-
return false;
|
|
457
|
-
|
|
458
|
-
for (; is < ls; is++, iok++) {
|
|
459
|
-
chs = src.charAt(is);
|
|
460
|
-
lastIs = is;
|
|
461
|
-
if (iok >= 0 && iok < lok)
|
|
462
|
-
chok = ok.charAt(iok);
|
|
463
|
-
else
|
|
464
|
-
chok = 0;
|
|
465
|
-
if (this.collator.compare(chs, chok) === 0) {
|
|
466
|
-
attr[is] = 0;
|
|
467
|
-
lastiok = true;
|
|
468
|
-
} else {
|
|
469
|
-
result = false;
|
|
470
|
-
attr[is] = 1;
|
|
471
|
-
if (!iterate && lastiok && chok !== 0 && this.checkSteps > 0 && this.checkScope > 0) {
|
|
472
|
-
const
|
|
473
|
-
lbloc = 2 * this.checkSteps + 1,
|
|
474
|
-
itcoinc = [];
|
|
475
|
-
let i = 0, j = 0;
|
|
476
|
-
for (; j < lbloc; j++) {
|
|
477
|
-
itcoinc[j] = 0;
|
|
478
|
-
i = iok + Math.floor((j + 1) / 2) * ((j & 1) !== 0 ? 1 : -1);
|
|
479
|
-
if (i >= lok)
|
|
480
|
-
continue;
|
|
481
|
-
const is2 = i < 0 ? is - i : is;
|
|
482
|
-
if (is2 >= ls)
|
|
483
|
-
continue;
|
|
484
|
-
const
|
|
485
|
-
ls2 = Math.min(ls - is2, this.checkScope),
|
|
486
|
-
iok2 = i < 0 ? 0 : i,
|
|
487
|
-
lok2 = Math.min(lok - iok2, this.checkScope),
|
|
488
|
-
flags2 = Array(src.length - is2).fill(0),
|
|
489
|
-
result2 = this.compareSegment(src.substring(is2), ls2, ok.substring(iok2), lok2, flags2, true);
|
|
490
|
-
itcoinc[j] = this.countFlagsOk(flags2);
|
|
491
|
-
if (result2)
|
|
492
|
-
break;
|
|
493
|
-
}
|
|
494
|
-
if (j === lbloc) {
|
|
495
|
-
let jmax = this.checkSteps;
|
|
496
|
-
for (j = 0; j < lbloc; j++)
|
|
497
|
-
if (itcoinc[j] > itcoinc[jmax])
|
|
498
|
-
jmax = j;
|
|
499
|
-
i = iok + Math.floor((jmax + 1) / 2) * ((jmax & 1) !== 0 ? 1 : -1);
|
|
500
|
-
}
|
|
501
|
-
iok = i;
|
|
502
|
-
lastiok = false;
|
|
503
|
-
}
|
|
504
|
-
}
|
|
505
|
-
}
|
|
506
|
-
if (iok !== lok) {
|
|
507
|
-
result = false;
|
|
508
|
-
attr[lastIs] = 1;
|
|
509
|
-
}
|
|
510
|
-
return result;
|
|
511
|
-
}
|
|
512
|
-
}
|
|
513
|
-
|
|
514
|
-
Object.assign(ComplexEvaluator.prototype, {
|
|
515
|
-
/**
|
|
516
|
-
* Whether to detail or not the location of errors found on the analyzed text.
|
|
517
|
-
* @name module:activities/text/Evaluator.ComplexEvaluator#detail
|
|
518
|
-
* @type {boolean} */
|
|
519
|
-
detail: true,
|
|
520
|
-
/**
|
|
521
|
-
* Number of times to repeat the evaluation process if an error is found, eliminating in each
|
|
522
|
-
* cycle the extra characters that caused the error.
|
|
523
|
-
* @name module:activities/text/Evaluator.ComplexEvaluator#checkSteps
|
|
524
|
-
* @type {number} */
|
|
525
|
-
checkSteps: 3,
|
|
526
|
-
/**
|
|
527
|
-
* When an eror is detected in the analyzed expression, this variable indicates the number of
|
|
528
|
-
* characters the checking pointer will be moved forward and back looking for a coincident
|
|
529
|
-
* expression.
|
|
530
|
-
*
|
|
531
|
-
* For example, comparing the answer "_one lardzy dog_" with the correct answer "_one lazy dog_"
|
|
532
|
-
* will detect an error at position 6 (an "r" instead of "z"). If `checkSteps` is set to 2 or
|
|
533
|
-
* greater, the "_zy dog_" expression at position 8 will be found and evaluated as valid, while
|
|
534
|
-
* a value of 1 or less will not found any coincident expression beyond the error position, thus
|
|
535
|
-
* evaluating all the remaining sentence as erroneous.
|
|
536
|
-
* @name module:activities/text/Evaluator.ComplexEvaluator#checkScope
|
|
537
|
-
* @type {number} */
|
|
538
|
-
checkScope: 6,
|
|
539
|
-
});
|
|
540
|
-
|
|
541
|
-
// List of known Evaluator classes
|
|
542
|
-
Evaluator.CLASSES = {
|
|
543
|
-
'@BasicEvaluator': BasicEvaluator,
|
|
544
|
-
'@ComplexEvaluator': ComplexEvaluator
|
|
545
|
-
};
|
|
546
|
-
|
|
547
|
-
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (Evaluator);
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
/***/ })
|
|
551
|
-
|
|
552
|
-
};
|
|
553
|
-
;
|
|
554
|
-
//# sourceMappingURL=2715.jclic-node.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"2715.jclic-node.js","mappings":";;;;;;;;;;;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEgF;;AAEhF;AACA,mCAAmC,sEAAsE;AACzG,IAAI,0EAA0E;AAC9E;AACA;AACO;AACP;AACA;AACA,aAAa,QAAQ;AACrB;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;;AAEA;AACA,0DAA0D,4DAA4D;AACtH;AACA,aAAa,iBAAiB;AAC9B,eAAe;AACf;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR,QAAQ,wDAAG,uCAAuC,UAAU;AAC5D;AACA;AACA;;AAEA;AACA;AACA,aAAa,iBAAiB;AAC9B;AACA;AACA,IAAI,gEAAW;AACf;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB,+DAAU;AACjC;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;;AAEA;AACA;AACA,aAAa,QAAQ;AACrB,eAAe;AACf;AACA;AACA;AACA;AACA;AACA,aAAa,4DAAO;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB;AACA;AACA,WAAW,4DAAO;AAClB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,aAAa,UAAU;AACvB;AACA;AACA;AACA;;AAEA;AACA;AACA,aAAa,QAAQ;AACrB,aAAa,iBAAiB;AAC9B,eAAe,SAAS;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,aAAa,QAAQ;AACrB,aAAa,QAAQ;AACrB,eAAe,SAAS;AACxB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,aAAa,QAAQ;AACrB,aAAa,iBAAiB;AAC9B,eAAe,UAAU;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,aAAa,QAAQ;AACrB,aAAa,QAAQ;AACrB,eAAe,UAAU;AACzB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,aAAa,UAAU;AACvB,eAAe,SAAS;AACxB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,YAAY,QAAQ;AACpB;AACA;AACA;AACA;AACA,YAAY,SAAS;AACrB;AACA;AACA;AACA;AACA,YAAY,mBAAmB;AAC/B;AACA;AACA;AACA;AACA,YAAY,SAAS;AACrB;AACA,CAAC;;AAED;AACA;AACA;AACA;AACA;AACO;AACP;AACA;AACA,aAAa,QAAQ;AACrB;AACA;AACA;AACA;;AAEA;AACA,sBAAsB,mEAAmE;AACzF;AACA,aAAa,UAAU;AACvB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA,aAAa,QAAQ;AACrB,aAAa,QAAQ;AACrB,eAAe,SAAS;AACxB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,MAAM,0EAA0E;AAChF;AACA,aAAa,QAAQ;AACrB,aAAa,QAAQ;AACrB,eAAe,UAAU;AACzB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,aAAa,QAAQ;AACrB,aAAa,WAAW;AACxB;AACA,eAAe;AACf;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA,sCAAsC,gBAAgB;AACtD;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,YAAY,SAAS;AACrB;AACA;AACA;AACA;AACA,YAAY,SAAS;AACrB;AACA;AACA;AACA;AACA,YAAY,SAAS;AACrB;AACA;AACA,yFAAyF;AACzF;AACA,YAAY,QAAQ;AACpB,mBAAmB;AACnB,CAAC;;AAED;AACA,+BAA+B,qEAAqE;AACpG;AACA;AACA;AACO;AACP;AACA;AACA,aAAa,QAAQ;AACrB;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,MAAM,0EAA0E;AAChF;AACA,aAAa,QAAQ;AACrB,aAAa,QAAQ;AACrB,eAAe,UAAU;AACzB;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,oBAAoB,kBAAkB;AACtC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,sBAAsB,kBAAkB;AACxC;AACA;AACA;AACA;AACA;AACA;;AAEA,2BAA2B,iBAAiB;AAC5C;;AAEA;AACA;;AAEA;AACA;AACA,aAAa,UAAU;AACvB,eAAe;AACf;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,aAAa,QAAQ;AACrB,aAAa,QAAQ;AACrB,aAAa,QAAQ;AACrB,aAAa,QAAQ;AACrB,aAAa,UAAU;AACvB;AACA,aAAa,SAAS;AACtB;AACA,eAAe,SAAS;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA,WAAW,SAAS;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,WAAW;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,WAAW;AACnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,YAAY,SAAS;AACrB;AACA;AACA;AACA;AACA;AACA,YAAY,QAAQ;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,QAAQ;AACpB;AACA,CAAC;;AAED;AACA;AACA;AACA;AACA;;AAEA,iEAAe,SAAS,EAAC","sources":["webpack://jclic/./src/activities/text/Evaluator.js"],"sourcesContent":["/**\n * File : activities/text/Evaluator.js\n * Created : 14/04/2015\n * By : Francesc Busquets <francesc@gmail.com>\n *\n * JClic.js\n * An HTML5 player of JClic activities\n * https://projectestac.github.io/jclic.js\n *\n * @source https://github.com/projectestac/jclic.js\n *\n * @license EUPL-1.2\n * @licstart\n * (c) 2000-2020 Educational Telematic Network of Catalonia (XTEC)\n *\n * Licensed under the EUPL, Version 1.1 or -as soon they will be approved by\n * the European Commission- subsequent versions of the EUPL (the \"Licence\");\n * You may not use this work except in compliance with the Licence.\n *\n * You may obtain a copy of the Licence at:\n * https://joinup.ec.europa.eu/software/page/eupl\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the Licence is distributed on an \"AS IS\" basis, WITHOUT\n * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n * Licence for the specific language governing permissions and limitations\n * under the Licence.\n * @licend\n * @module\n */\n\n/* global window */\n\nimport { log, attrForEach, getBoolean, setAttr, getAttr } from '../../Utils.js';\n\n/**\n * This class and its derivatives {@link module:activities/text/Evaluator.BasicEvaluator BasicEvaluator} and\n * {@link module:activities/text/Evaluator.ComplexEvaluator ComplexEvaluator} are used to evaluate the answers written by the final users\n * in text activities.\n */\nexport class Evaluator {\n /**\n * Evaluator constructor\n * @param {string} className - The class name of this evaluator.\n */\n constructor(className) {\n this.className = className;\n this.collator = (window.Intl && window.Intl.Collator) ?\n new window.Intl.Collator() :\n { compare: (a, b) => this.checkCase ? a === b : a.toUpperCase() === b.toUpperCase() };\n }\n\n /**\n * Factory constructor that returns a specific type of {@link module:activities/text/Evaluator.Evaluator Evaluator} based on the `class`\n * attribute declared in the $xml element.\n * @param {external:jQuery} $xml - The XML element to be parsed.\n * @returns {module:activities/text/Evaluator.Evaluator}\n */\n static getEvaluator($xml) {\n let ev = null;\n if ($xml) {\n const className = $xml.attr('class');\n const cl = Evaluator.CLASSES[className];\n if (cl) {\n ev = new cl(className);\n ev.setProperties($xml);\n } else\n log('error', `Unknown evaluator class: \"${className}\"`);\n }\n return ev;\n }\n\n /**\n * Loads the object settings from a specific JQuery XML element\n * @param {external:jQuery} $xml - The jQuery XML element to parse\n */\n setProperties($xml) {\n attrForEach($xml.get(0).attributes, (name, value) => {\n switch (name) {\n case 'class':\n this.className = value;\n break;\n case 'checkCase':\n case 'checkAccents':\n case 'checkPunctuation':\n case 'checkDoubleSpaces':\n case 'detail':\n this[name] = getBoolean(value);\n break;\n case 'checkSteps':\n case 'checkScope':\n this[name] = Number(value);\n break;\n }\n });\n return this;\n }\n\n /**\n * Builds a new Evaluator, based on the properties specified in a data object\n * @param {object} data - The data object to be parsed\n * @returns {module:activities/text/Evaluator.Evaluator}\n */\n static factory(data) {\n const cl = Evaluator.CLASSES[data.className];\n if (cl) {\n const result = new cl(data.className);\n return setAttr(result, data, [\n 'className',\n 'checkCase', 'checkAccents', 'checkPunctuation', 'checkDoubleSpaces', 'detail',\n 'checkSteps', 'checkScope',\n ]);\n }\n return null;\n }\n\n /**\n * Gets a object with the basic attributes needed to rebuild this instance excluding functions,\n * parent references, constants and also attributes retaining the default value.\n * The resulting object is commonly usued to serialize elements in JSON format.\n * @returns {object} - The resulting object, with minimal attrributes\n */\n getAttributes() {\n return getAttr(this, [\n 'className',\n 'checkCase', 'checkAccents', 'checkPunctuation', 'checkDoubleSpaces', 'detail',\n 'checkSteps', 'checkScope',\n ]);\n }\n\n /**\n * Initializes this evaluator\n * @param {string[]} _locales - An array of valid locales, to be used by Intl.Collator\n */\n init(_locales) {\n this.initiated = true;\n }\n\n /**\n * Checks the given text against a set of valid matches\n * @param {string} text - The text to be checked\n * @param {string|string[]} match - The valid expression or expressions with which to compare.\n * @returns {boolean} - `true` if the checked expression is valid, `false` otherwise.\n */\n checkText(text, match) {\n if (match instanceof Array)\n return match.some(m => this._checkText(text, m));\n else if (match)\n return this._checkText(text, match);\n else\n return false;\n }\n\n /**\n * Abstract method to be implemented in subclasses.\n * Performs the validation of a string against a single match.\n * @param {string} _text - The text to be checked\n * @param {string} _match - A valid expression with which to compare.\n * @returns {boolean} - `true` when the two expressions can be considered equivalent.\n */\n _checkText(_text, _match) {\n return false;\n }\n\n /**\n * Evaluates the given text against a set of valid matches, returning an array of flags useful\n * to indicate where the mistakes are located.\n * @param {string} text - The text to be checked\n * @param {string|string[]} match - The valid expression or expressions with which to compare.\n * @returns {number[]} - An array of flags (one number for character) indicating whether each\n * position is erroneous or ok.\n */\n evalText(text, match) {\n if (!(match instanceof Array))\n match = [match];\n return this._evalText(text, match);\n }\n\n /**\n * Abstract method to be implemented in subclasses.\n * Performs the evaluation of a string against an array of valid matches, returning an array of\n * flags useful to indicate where the mistakes are located.\n * @param {string} _text - The text to be checked\n * @param {string} _match - A valid expression with which to compare.\n * @returns {number[]} - An array of flags (one number for character) indicating whether each\n * position is erroneous or OK.\n */\n _evalText(_text, _match) {\n return [];\n }\n\n /**\n * Checks if the given array of flags (usually returned by `evalText`) can be considered as a\n * valid or erroneous answer.\n * @param {number[]} flags\n * @returns {boolean} - `true` when there is at least one flag and all flags are 0 (meaning no error).\n */\n isOk(flags) {\n return flags && flags.length > 0 && !flags.some(f => f !== 0);\n }\n}\n\nObject.assign(Evaluator.prototype, {\n /**\n * The type of evaluator.\n * @name module:activities/text/Evaluator.Evaluator#className\n * @type {string} */\n className: null,\n /**\n * Whether this evaluator has been initialized or not.\n * @name module:activities/text/Evaluator.Evaluator#initiated\n * @type {boolean} */\n initiated: false,\n /**\n * The Intl.Collator object used to compare strings, when available.\n * @name module:activities/text/Evaluator.Evaluator#collator\n * @type {external:Collator} */\n collator: null,\n /**\n * Whether uppercase and lowercase expressions must be considered equivalent or not.\n * @name module:activities/text/Evaluator.Evaluator#checkcase\n * @type {boolean} */\n checkCase: false,\n});\n\n/**\n * A basic evaluator that just compares texts, without looking for possible coincidences of text\n * fragments once erroneous characters removed.\n * @extends module:activities/text/Evaluator.Evaluator\n */\nexport class BasicEvaluator extends Evaluator {\n /**\n * BasicEvaluator constructor\n * @param {string} className - The class name of this evaluator.\n */\n constructor(className) {\n super(className);\n }\n\n /**\n * Initializes the {@link module:activities/text/Evaluator.Evaluator#collator collator}.\n * @override\n * @param {string[]} locales - An array of valid locales to be used by the Inlt.Collator object\n */\n init(locales) {\n // Call `init` method on ancestor\n super.init([locales]);\n\n // Get canonical locales\n if (window.Intl && window.Intl.Collator) {\n this.collator = new window.Intl.Collator(locales, {\n sensitivity: this.checkAccents ? this.checkCase ? 'case' : 'accent' : 'base',\n ignorePunctuation: !this.checkPunctuation\n });\n }\n }\n\n /**\n * Performs the validation of a string against a single match.\n * @override\n * @param {string} text - The text to be checked\n * @param {string} match - A valid expression with which to compare.\n * @returns {boolean} - `true` when the two expressions can be considered equivalent.\n */\n _checkText(text, match) {\n return this.collator.compare(this.getClearedText(text), this.getClearedText(match)) === 0;\n }\n\n /**\n * Performs the evaluation of a string against an array of valid matches, returning an array of\n * flags useful to indicate where the mistakes are located.\n * In BasicEvaluator, all characters are just marked as 1 (error) or 0 (OK). See\n * {@link module:activities/text/Evaluator.ComplexEvaluator ComplexEvaluator} for more detailed analysis of answers.\n * @override\n * @param {string} text - The text to be checked\n * @param {string} match - A valid expression with which to compare.\n * @returns {number[]} - An array of flags (one number for character) indicating whether each\n * position is erroneous or OK.\n */\n _evalText(text, match) {\n return Array(text.length).fill(this._checkText(text, match[0]) ? 0 : 1);\n }\n\n /**\n * Removes double spaces and erroneous characters from a given text expression.\n * @param {string} src - The text to be processed.\n * @param {boolean[]} skipped - An array of boolean indicating which characters should be removed\n * from the string.\n * @returns {string}\n */\n getClearedText(src, skipped) {\n if (this.checkPunctuation && this.checkDoubleSpaces)\n return src;\n\n if (!skipped)\n skipped = Array(src.length).fill(false);\n\n let sb = '';\n for (let i = 0, wasSpace = false; i < src.length; i++) {\n const ch = src.charAt(i);\n if (this.PUNCTUATION.indexOf(ch) >= 0 && !this.checkPunctuation) {\n if (!wasSpace)\n sb += ' ';\n else\n skipped[i] = true;\n wasSpace = true;\n } else if (ch === ' ') {\n if (this.checkDoubleSpaces || !wasSpace)\n sb += ch;\n else\n skipped[i] = true;\n wasSpace = true;\n } else {\n wasSpace = false;\n sb += ch;\n }\n }\n return sb;\n }\n}\n\nObject.assign(BasicEvaluator.prototype, {\n /**\n * Whether accented letters must be considered equivalent or not.\n * @name module:activities/text/Evaluator.BasicEvaluator#checkAccents\n * @type {boolean} */\n checkAccents: true,\n /**\n * Whether to check or not dots, commas and other punctuation marks when comparing texts.\n * @name module:activities/text/Evaluator.BasicEvaluator#checkPunctuation\n * @type {boolean} */\n checkPunctuation: true,\n /**\n * Whether to check or not the extra spaces added between words.\n * @name module:activities/text/Evaluator.BasicEvaluator#checkDoubleSpaces\n * @type {boolean} */\n checkDoubleSpaces: false,\n /**\n * String containing all the characters considered as punctuation marks (currently \".,;:\")\n * @name module:activities/text/Evaluator.BasicEvaluator#PUNCTUATION\n * @type {string} */\n PUNCTUATION: '.,;:',\n});\n\n/**\n * ComplexEvaluator acts like {@link module:activities/text/Evaluator.BasicEvaluator BasicEvaluator}, but providing feedback about\n * the location of mistakes on the user's answer.\n * @extends module:activities/text/Evaluator.BasicEvaluator\n */\nexport class ComplexEvaluator extends BasicEvaluator {\n /**\n * ComplexEvaluator constructor\n * @param {string} className - The class name of this evaluator.\n */\n constructor(className) {\n super(className);\n }\n\n /**\n * Performs the evaluation of a string against an array of valid matches, returning an array of\n * flags useful to indicate where the mistakes are located.\n * In BasicEvaluator, all characters are just marked as 1 (error) or 0 (OK). See\n * {@link module:activities/text/Evaluator.ComplexEvaluator ComplexEvaluator} for more detailed analysis of answers.\n * @override\n * @param {string} text - The text to be checked\n * @param {string} match - A valid expression with which to compare.\n * @returns {number[]} - An array of flags (one number for character) indicating whether each\n * position is erroneous or OK.\n */\n _evalText(text, match) {\n\n if (!this.detail)\n return super._evalText(text, match);\n\n const\n skipped = Array(text.length).fill(false),\n sText = this.getClearedText(text, skipped),\n numChecks = Array(match.length),\n flags = Array(match.length),\n returnFlags = Array(text.length);\n let\n maxCheck = -1,\n maxCheckIndex = -1;\n\n for (let i = 0; i < match.length; i++) {\n flags[i] = Array(text.length).fill(0);\n const ok = this.compareSegment(sText, sText.length, match[i], match[i].length, flags[i], false);\n numChecks[i] = this.countFlagsOk(flags[i]);\n if (ok) {\n maxCheckIndex = i;\n maxCheck = numChecks[i];\n }\n }\n\n if (maxCheckIndex === -1) {\n for (let i = 0; i < match.length; i++) {\n if (numChecks[i] > maxCheck) {\n maxCheck = numChecks[i];\n maxCheckIndex = i;\n }\n }\n }\n\n for (let i = 0, k = 0; i < text.length; i++)\n returnFlags[i] = skipped[i] ? 0 : flags[maxCheckIndex][k++];\n\n return returnFlags;\n }\n\n /**\n * Counts the number of flags on the provided array that are zero.\n * @param {number[]} flags\n * @returns {number}\n */\n countFlagsOk(flags) {\n return flags.reduce((n, v) => v == 0 ? ++n : n, 0);\n }\n\n /**\n * Compares two segments of text.\n * This function should make recursive calls.\n * @param {string} src - Text to be compared\n * @param {number} ls - Offset in `src` where to start the comparison\n * @param {string} ok - Text to match against.\n * @param {number} lok - Offset in `ok` where to start the comparison.\n * @param {number[]} attr - Array of integers that will be filled with information about the\n * validity or error of each character in `src`.\n * @param {boolean} iterate - When `true`, the segment will be iterated looking for other\n * coincident fragments.\n * @returns {boolean} - `true` if the comparison was valid.\n */\n compareSegment(src, ls, ok, lok, attr, iterate) {\n let\n is = 0,\n iok = 0,\n lastIs = 0,\n lastiok = true,\n result = true,\n chs = '',\n chok = '';\n\n if (ls === 0 || lok === 0 || src === null || ok === null)\n return false;\n\n for (; is < ls; is++, iok++) {\n chs = src.charAt(is);\n lastIs = is;\n if (iok >= 0 && iok < lok)\n chok = ok.charAt(iok);\n else\n chok = 0;\n if (this.collator.compare(chs, chok) === 0) {\n attr[is] = 0;\n lastiok = true;\n } else {\n result = false;\n attr[is] = 1;\n if (!iterate && lastiok && chok !== 0 && this.checkSteps > 0 && this.checkScope > 0) {\n const\n lbloc = 2 * this.checkSteps + 1,\n itcoinc = [];\n let i = 0, j = 0;\n for (; j < lbloc; j++) {\n itcoinc[j] = 0;\n i = iok + Math.floor((j + 1) / 2) * ((j & 1) !== 0 ? 1 : -1);\n if (i >= lok)\n continue;\n const is2 = i < 0 ? is - i : is;\n if (is2 >= ls)\n continue;\n const\n ls2 = Math.min(ls - is2, this.checkScope),\n iok2 = i < 0 ? 0 : i,\n lok2 = Math.min(lok - iok2, this.checkScope),\n flags2 = Array(src.length - is2).fill(0),\n result2 = this.compareSegment(src.substring(is2), ls2, ok.substring(iok2), lok2, flags2, true);\n itcoinc[j] = this.countFlagsOk(flags2);\n if (result2)\n break;\n }\n if (j === lbloc) {\n let jmax = this.checkSteps;\n for (j = 0; j < lbloc; j++)\n if (itcoinc[j] > itcoinc[jmax])\n jmax = j;\n i = iok + Math.floor((jmax + 1) / 2) * ((jmax & 1) !== 0 ? 1 : -1);\n }\n iok = i;\n lastiok = false;\n }\n }\n }\n if (iok !== lok) {\n result = false;\n attr[lastIs] = 1;\n }\n return result;\n }\n}\n\nObject.assign(ComplexEvaluator.prototype, {\n /**\n * Whether to detail or not the location of errors found on the analyzed text.\n * @name module:activities/text/Evaluator.ComplexEvaluator#detail\n * @type {boolean} */\n detail: true,\n /**\n * Number of times to repeat the evaluation process if an error is found, eliminating in each\n * cycle the extra characters that caused the error.\n * @name module:activities/text/Evaluator.ComplexEvaluator#checkSteps\n * @type {number} */\n checkSteps: 3,\n /**\n * When an eror is detected in the analyzed expression, this variable indicates the number of\n * characters the checking pointer will be moved forward and back looking for a coincident\n * expression.\n *\n * For example, comparing the answer \"_one lardzy dog_\" with the correct answer \"_one lazy dog_\"\n * will detect an error at position 6 (an \"r\" instead of \"z\"). If `checkSteps` is set to 2 or\n * greater, the \"_zy dog_\" expression at position 8 will be found and evaluated as valid, while\n * a value of 1 or less will not found any coincident expression beyond the error position, thus\n * evaluating all the remaining sentence as erroneous.\n * @name module:activities/text/Evaluator.ComplexEvaluator#checkScope\n * @type {number} */\n checkScope: 6,\n});\n\n// List of known Evaluator classes\nEvaluator.CLASSES = {\n '@BasicEvaluator': BasicEvaluator,\n '@ComplexEvaluator': ComplexEvaluator\n};\n\nexport default Evaluator;\n"],"names":[],"sourceRoot":""}
|