fcad-core-dragon 2.1.0-beta.4 → 2.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/.editorconfig +8 -33
  2. package/.prettierrc +11 -0
  3. package/.vscode/extensions.json +8 -0
  4. package/.vscode/settings.json +16 -0
  5. package/CHANGELOG +20 -0
  6. package/eslint.config.js +60 -0
  7. package/package.json +9 -9
  8. package/src/$locales/en.json +3 -3
  9. package/src/$locales/fr.json +3 -3
  10. package/src/assets/data/onboardingMessages.json +47 -47
  11. package/src/components/AppBase.vue +5 -6
  12. package/src/components/AppBaseErrorDisplay.vue +438 -438
  13. package/src/components/AppBaseFlipCard.vue +84 -84
  14. package/src/components/AppBaseModule.vue +15 -17
  15. package/src/components/AppBasePage.vue +91 -8
  16. package/src/components/AppBasePopover.vue +41 -41
  17. package/src/components/AppBaseSkeleton.vue +24 -3
  18. package/src/components/AppCompAudio.vue +12 -2
  19. package/src/components/AppCompInputCheckBoxNx.vue +1 -2
  20. package/src/components/AppCompInputRadioNx.vue +8 -2
  21. package/src/components/AppCompInputTextToFillDropdownNx.vue +45 -0
  22. package/src/components/AppCompMenu.vue +423 -423
  23. package/src/components/AppCompNavigation.vue +2 -2
  24. package/src/components/AppCompPlayBarNext.vue +123 -94
  25. package/src/components/AppCompPopUpNext.vue +2 -2
  26. package/src/components/AppCompQuizNext.vue +12 -2
  27. package/src/components/AppCompQuizRecall.vue +10 -4
  28. package/src/components/AppCompSettingsMenu.vue +172 -172
  29. package/src/components/AppCompTableOfContent.vue +1 -4
  30. package/src/components/AppCompVideoPlayer.vue +7 -0
  31. package/src/components/AppCompViewDisplay.vue +6 -6
  32. package/src/composables/useTimer.js +17 -20
  33. package/src/externalComps/ModuleView.vue +22 -22
  34. package/src/externalComps/SummaryView.vue +91 -91
  35. package/src/main.js +5 -5
  36. package/src/module/stores/appStore.js +0 -1
  37. package/src/module/xapi/Crypto/Hasher.js +241 -241
  38. package/src/module/xapi/Crypto/WordArray.js +278 -278
  39. package/src/module/xapi/Crypto/algorithms/BufferedBlockAlgorithm.js +103 -103
  40. package/src/module/xapi/Crypto/algorithms/C_algo.js +315 -315
  41. package/src/module/xapi/Crypto/algorithms/HMAC.js +9 -9
  42. package/src/module/xapi/Crypto/algorithms/SHA1.js +9 -9
  43. package/src/module/xapi/Crypto/encoders/Base.js +105 -105
  44. package/src/module/xapi/Crypto/encoders/Base64.js +99 -99
  45. package/src/module/xapi/Crypto/encoders/Hex.js +61 -61
  46. package/src/module/xapi/Crypto/encoders/Latin1.js +61 -61
  47. package/src/module/xapi/Crypto/encoders/Utf8.js +45 -45
  48. package/src/module/xapi/Crypto/index.js +53 -53
  49. package/src/module/xapi/Statement/activity.js +47 -47
  50. package/src/module/xapi/Statement/agent.js +55 -55
  51. package/src/module/xapi/Statement/group.js +26 -26
  52. package/src/module/xapi/Statement/index.js +259 -259
  53. package/src/module/xapi/Statement/statement.js +253 -253
  54. package/src/module/xapi/Statement/statementRef.js +23 -23
  55. package/src/module/xapi/Statement/substatement.js +22 -22
  56. package/src/module/xapi/Statement/verb.js +36 -36
  57. package/src/module/xapi/activitytypes.js +17 -17
  58. package/src/module/xapi/utils.js +167 -167
  59. package/src/module/xapi/verbs.js +294 -294
  60. package/src/module/xapi/xapiStatement.js +444 -444
  61. package/src/plugins/analytics.js +4 -4
  62. package/src/plugins/bus.js +8 -8
  63. package/src/plugins/gsap.js +4 -2
  64. package/src/plugins/helper.js +8 -4
  65. package/src/plugins/save.js +37 -37
  66. package/src/plugins/scorm.js +287 -287
  67. package/src/plugins/xapi.js +11 -11
  68. package/src/public/index.html +33 -33
  69. package/src/router/index.js +1 -1
  70. package/src/shared/validators.js +22 -6
  71. package/.eslintignore +0 -29
  72. package/.eslintrc.cjs +0 -81
  73. package/bk.scss +0 -117
@@ -1,444 +1,444 @@
1
- import verbs from './verbs'
2
-
3
- export function xapiStatement(ADL) {
4
- function _getobj(obj, path) {
5
- var parts = path.split('.')
6
-
7
- var part = parts[0]
8
- path = parts.slice(1).join('.')
9
-
10
- if (!obj[part]) {
11
- if (/\[\]$/.test(part)) {
12
- part = part.slice(0, -2)
13
- if (!Array.isArray(obj[part])) {
14
- obj[part] = []
15
- }
16
- } else obj[part] = {}
17
- }
18
-
19
- if (!path) return obj[part]
20
- else return _getobj(obj[part], path)
21
- }
22
-
23
- /*******************************************************************************
24
- * XAPIStatement - a convenience class to wrap statement objects
25
- *
26
- * This sub-API is supposed to make it easier to author valid xAPI statements
27
- * by adding constructors and encouraging best practices. All objects in this
28
- * API are fully JSON-compatible, so anything expecting an xAPI statement can
29
- * take an improved statement and vice versa.
30
- *
31
- * A working knowledge of what exactly the LRS expects is still expected,
32
- * but it's easier to map an 'I did this' statement to xAPI now.
33
- *
34
- * Tech note: All constructors also double as shallow clone functions. E.g.
35
- *
36
- * var activity1 = new Activity('A walk in the park');
37
- * var activity2 = new Activity(activity1);
38
- * var activity3 = new Activity(stmt_from_lrs.object);
39
- *
40
- *******************************************************************************/
41
-
42
- /*
43
- * A convenient JSON-compatible xAPI statement wrapper
44
- * All args are optional, but the statement may not be complete or valid
45
- * Can also pass an Agent IFI, Verb ID, and an Activity ID in lieu of these args
46
- * @param {string} [actor] The Agent or Group committing the action described by the statement
47
- * @param {string} [verb] The Verb for the action described by the statement
48
- * @param {string} [object] The receiver of the action. An Agent, Group, Activity, SubStatement, or StatementRef
49
- * @example
50
- * var stmt = new ADL.XAPIStatement(
51
- * 'mailto:steve.vergenz.ctr@adlnet.gov',
52
- * 'http://adlnet.gov/expapi/verbs/launched',
53
- * 'http://vwf.adlnet.gov/xapi/virtual_world_sandbox'
54
- * );
55
- * >> {
56
- * "actor": {
57
- * "objectType": "Agent",
58
- * "mbox": "mailto:steve.vergenz.ctr@adlnet.gov" },
59
- * "verb": {
60
- * "id": "http://adlnet.gov/expapi/verbs/launched" },
61
- * "object": {
62
- * "objectType": "Activity",
63
- * "id": "http://vwf.adlnet.gov/xapi/virtual_world_sandbox" },
64
- * "result": {
65
- * "An optional property that represents a measured outcome related to the Statement in which it is included."}}
66
- */
67
- var XAPIStatement = function (actor, verb, object, context, result) {
68
- // initialize
69
-
70
- // if first arg is an xapi statement, parse
71
- if (actor && actor.actor && actor.verb && actor.object) {
72
- var stmt = actor
73
- for (var i in stmt) {
74
- if (i != 'actor' && i != 'verb' && i != 'object') this[i] = stmt[i]
75
- }
76
- actor = stmt.actor
77
- verb = stmt.verb
78
- object = stmt.object
79
- }
80
-
81
- if (actor) {
82
- if (actor instanceof Agent) this.actor = actor
83
- else if (actor.objectType === 'Agent' || !actor.objectType)
84
- this.actor = new Agent(actor)
85
- else if (actor.objectType === 'Group') this.actor = new Group(actor)
86
- } else this.actor = null
87
-
88
- if (verb) {
89
- this._setVerb(verb)
90
- // if (verb instanceof Verb) this.verb = verb
91
- // else this.verb = new Verb(verb)
92
- } else this.verb = null
93
-
94
- // decide what kind of object was passed
95
- if (object) {
96
- // if (object.objectType === 'Activity' || !object.objectType) {
97
- // if (object instanceof Activity) this.object = object
98
- // else this.object = new Activity(object)
99
- // } else if (object.objectType === 'Agent') {
100
- // if (object instanceof Agent) this.object = object
101
- // else this.object = new Agent(object)
102
- // } else if (object.objectType === 'Group') {
103
- // if (object instanceof Group) this.object = object
104
- // else this.object = new Group(object)
105
- // } else if (object.objectType === 'StatementRef') {
106
- // if (object instanceof StatementRef) this.object = object
107
- // else this.object = new StatementRef(object)
108
- // } else if (object.objectType === 'SubStatement') {
109
- // if (object instanceof SubStatement) this.object = object
110
- // else this.object = new SubStatement(object)
111
- // } else this.object = null
112
- this._setObject(object)
113
- } else this.object = null
114
-
115
- // add support for result object
116
- if (result) {
117
- this.result = result
118
- }
119
-
120
- // add support for result context
121
- if (context) {
122
- this.context = context
123
- }
124
-
125
- this.generateId = function () {
126
- this.id = ADL.ruuid()
127
- }
128
- }
129
-
130
- XAPIStatement.prototype.toString = function () {
131
- return (
132
- this.actor.toString() +
133
- ' ' +
134
- this.verb.toString() +
135
- ' ' +
136
- this.object.toString() +
137
- ' ' +
138
- this.result.toString()
139
- )
140
- }
141
-
142
- XAPIStatement.prototype.isValid = function () {
143
- return (
144
- this.actor &&
145
- this.actor.isValid() &&
146
- this.verb &&
147
- this.verb.isValid() &&
148
- this.object &&
149
- this.object.isValid() &&
150
- this.result &&
151
- this.result.isValid()
152
- )
153
- }
154
-
155
- XAPIStatement.prototype.generateRegistration = function () {
156
- _getobj(this, 'context').registration = ADL.ruuid()
157
- }
158
-
159
- XAPIStatement.prototype.addParentActivity = function (activity) {
160
- _getobj(this, 'context.contextActivities.parent[]').push(
161
- new Activity(activity)
162
- )
163
- }
164
-
165
- XAPIStatement.prototype.addGroupingActivity = function (activity) {
166
- _getobj(this, 'context.contextActivities.grouping[]').push(
167
- new Activity(activity)
168
- )
169
- }
170
-
171
- XAPIStatement.prototype.addOtherContextActivity = function (activity) {
172
- _getobj(this, 'context.contextActivities.other[]').push(
173
- new Activity(activity)
174
- )
175
- }
176
-
177
- ///////////////////////////////////////////////////////////////
178
- XAPIStatement.prototype._setActor = function (email, name, objectType) {
179
- let actor = {
180
- mbox: 'mailto:' + email,
181
- name: name,
182
- objectType: ''
183
- }
184
- actor.objectType = objectType || 'Agent'
185
-
186
- this.actor = actor
187
- }
188
-
189
- /* helper function to set/change the verb of a statement
190
- * @Params {String | Object} verb
191
- *
192
- */
193
- XAPIStatement.prototype._setVerb = function (verb) {
194
- if (verb instanceof Verb) this.verb = verb
195
- else if (verbs[verb]) this.verb = verbs[verb]
196
- else this.verb = new Verb(verb)
197
- }
198
-
199
- XAPIStatement.prototype._setObject = function (object) {
200
- if (object.objectType === 'Activity' || !object.objectType) {
201
- if (object instanceof Activity) this.object = object
202
- else this.object = new Activity(object)
203
- } else if (object.objectType === 'Agent') {
204
- if (object instanceof Agent) this.object = object
205
- else this.object = new Agent(object)
206
- } else if (object.objectType === 'Group') {
207
- if (object instanceof Group) this.object = object
208
- else this.object = new Group(object)
209
- } else if (object.objectType === 'StatementRef') {
210
- if (object instanceof StatementRef) this.object = object
211
- else this.object = new StatementRef(object)
212
- } else if (object.objectType === 'SubStatement') {
213
- if (object instanceof SubStatement) this.object = object
214
- else this.object = new SubStatement(object)
215
- } else this.object = null
216
- }
217
-
218
- XAPIStatement.prototype._setResultScore = function (
219
- score,
220
- scoreScale,
221
- scoreMin,
222
- scoreMax
223
- ) {
224
- if (!this.result) this.result = {}
225
- this.result.score = {
226
- scaled: scoreScale || 1,
227
- min: scoreMin,
228
- max: scoreMax,
229
- raw: score
230
- }
231
- }
232
-
233
- XAPIStatement.prototype._setResultKey = function (key, value) {
234
- if (!this.result) this.result = {} //define the result key
235
- //define the extra keys of the result
236
- if (key == 'success') this.result.success = value
237
- else if (key == 'response') this.result.response = value
238
- else if (key == 'duration') this.result.duration = value
239
- else if (key == 'extensions') this.result.extensions = value
240
- else if (key == 'completion') this.result.completion = value
241
- }
242
-
243
- XAPIStatement.prototype._setContext = function (context) {
244
- if (typeof context !== 'object') throw 'this not a valid context'
245
- if (!this.context)
246
- Object.defineProperty(this, 'context', { value: {}, writable: true })
247
- this.context = { ...context }
248
-
249
- // if (key == 'instructor') this.context.instructor = value
250
- // else if (key == 'contextActivities') this.context.contextActivities = value
251
- }
252
-
253
- ///////////////////////////////////////////////////////////////
254
-
255
- /*
256
- * Provides an easy constructor for xAPI agent objects
257
- * @param {string} identifier One of the Inverse Functional Identifiers specified in the spec.
258
- * That is, an email, a hashed email, an OpenID, or an account object.
259
- * See (https://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#inversefunctional)
260
- * @param {string} [name] The natural-language name of the agent
261
- */
262
- var Agent = function (identifier, name) {
263
- this.objectType = 'Agent'
264
- this.name = name
265
-
266
- // figure out what type of identifier was given
267
- if (
268
- identifier &&
269
- (identifier.mbox ||
270
- identifier.mbox_sha1sum ||
271
- identifier.openid ||
272
- identifier.account)
273
- ) {
274
- for (var i in identifier) {
275
- this[i] = identifier[i]
276
- }
277
- } else if (/^mailto:/.test(identifier)) {
278
- this.mbox = identifier
279
- } else if (/^[0-9a-f]{40}$/i.test(identifier)) {
280
- this.mbox_sha1sum = identifier
281
- } else if (/^http[s]?:/.test(identifier)) {
282
- this.openid = identifier
283
- } else if (identifier && identifier.homePage && identifier.name) {
284
- this.account = identifier
285
- }
286
- }
287
- Agent.prototype.toString = function () {
288
- return (
289
- this.name ||
290
- this.mbox ||
291
- this.openid ||
292
- this.mbox_sha1sum ||
293
- this.account.name
294
- )
295
- }
296
- Agent.prototype.isValid = function () {
297
- return (
298
- this.mbox ||
299
- this.mbox_sha1sum ||
300
- this.openid ||
301
- (this.account.homePage && this.account.name) ||
302
- (this.objectType === 'Group' && this.member)
303
- )
304
- }
305
-
306
- /*
307
- * A type of agent, can contain multiple agents
308
- * @param {string} [identifier] (optional if `members` specified) See Agent.
309
- * @param {string} [members] An array of Agents describing the membership of the group
310
- * @param {string} [name] The natural-language name of the agent
311
- */
312
- var Group = function (identifier, members, name) {
313
- Agent.call(this, identifier, name)
314
- this.member = members
315
- this.objectType = 'Group'
316
- }
317
- Group.prototype = new Agent()
318
-
319
- /*
320
- * Really only provides a convenient language map
321
- * @param {string} id The IRI of the action taken
322
- * @param {string} [description] An English-language description, or a Language Map
323
- */
324
- var Verb = function (id, description) {
325
- // if passed a verb object then copy and return
326
- if (id && id.id) {
327
- for (var i in id) {
328
- this[i] = id[i]
329
- }
330
- return
331
- }
332
-
333
- // save id and build language map
334
- this.id = id
335
- if (description) {
336
- if (typeof description === 'string' || description instanceof String) {
337
- this.display = { 'en-US': description }
338
- } else {
339
- this.display = description
340
- }
341
- }
342
- }
343
- Verb.prototype.toString = function () {
344
- if (this.display && (this.display['en-US'] || this.display['en']))
345
- return this.display['en-US'] || this.display['en']
346
- else return this.id
347
- }
348
- Verb.prototype.isValid = function () {
349
- return this.id
350
- }
351
-
352
- /*
353
- * Describes an object that an agent interacts with
354
- * @param {string} id The unique activity IRI
355
- * @param {string} name An English-language identifier for the activity, or a Language Map
356
- * @param {string} description An English-language description of the activity, or a Language Map
357
- */
358
- var Activity = function (id, name, description) {
359
- // if first arg is activity, copy everything over
360
- if (id && id.id) {
361
- var act = id
362
- for (var i in act) {
363
- this[i] = act[i]
364
- }
365
- return
366
- }
367
-
368
- this.objectType = 'Activity'
369
- this.id = id
370
- if (name || description) {
371
- this.definition = {}
372
-
373
- if (typeof name === 'string' || name instanceof String)
374
- this.definition.name = { 'en-US': name }
375
- else if (name) this.definition.name = name
376
-
377
- if (typeof description === 'string' || description instanceof String)
378
- this.definition.description = { 'en-US': description }
379
- else if (description) this.definition.description = description
380
- }
381
- }
382
- Activity.prototype.toString = function () {
383
- if (
384
- this.definition &&
385
- this.definition.name &&
386
- (this.definition.name['en-US'] || this.definition.name['en'])
387
- )
388
- return this.definition.name['en-US'] || this.definition.name['en']
389
- else return this.id
390
- }
391
- Activity.prototype.isValid = function () {
392
- return this.id && (!this.objectType || this.objectType === 'Activity')
393
- }
394
-
395
- /*
396
- * An object that refers to a separate statement
397
- * @param {string} id The UUID of another xAPI statement
398
- */
399
- var StatementRef = function (id) {
400
- if (id && id.id) {
401
- for (var i in id) {
402
- this[i] = id[i]
403
- }
404
- } else {
405
- this.objectType = 'StatementRef'
406
- this.id = id
407
- }
408
- }
409
- StatementRef.prototype.toString = function () {
410
- return 'statement(' + this.id + ')'
411
- }
412
- StatementRef.prototype.isValid = function () {
413
- return this.id && this.objectType && this.objectType === 'StatementRef'
414
- }
415
-
416
- /*
417
- * A self-contained statement as the object of another statement
418
- * See XAPIStatement for constructor details
419
- * @param {string} actor The Agent or Group committing the action described by the statement
420
- * @param {string} verb The Verb for the action described by the statement
421
- * @param {string} object The receiver of the action. An Agent, Group, Activity, or StatementRef
422
- */
423
- var SubStatement = function (actor, verb, object) {
424
- XAPIStatement.call(this, actor, verb, object)
425
- this.objectType = 'SubStatement'
426
-
427
- delete this.id
428
- delete this.stored
429
- delete this.version
430
- delete this.authority
431
- }
432
- SubStatement.prototype = new XAPIStatement()
433
- SubStatement.prototype.toString = function () {
434
- return '"' + SubStatement.prototype.prototype.toString.call(this) + '"'
435
- }
436
-
437
- XAPIStatement.Agent = Agent
438
- XAPIStatement.Group = Group
439
- XAPIStatement.Verb = Verb
440
- XAPIStatement.Activity = Activity
441
- XAPIStatement.StatementRef = StatementRef
442
- XAPIStatement.SubStatement = SubStatement
443
- ADL.XAPIStatement = XAPIStatement
444
- }
1
+ import verbs from './verbs'
2
+
3
+ export function xapiStatement(ADL) {
4
+ function _getobj(obj, path) {
5
+ var parts = path.split('.')
6
+
7
+ var part = parts[0]
8
+ path = parts.slice(1).join('.')
9
+
10
+ if (!obj[part]) {
11
+ if (/\[\]$/.test(part)) {
12
+ part = part.slice(0, -2)
13
+ if (!Array.isArray(obj[part])) {
14
+ obj[part] = []
15
+ }
16
+ } else obj[part] = {}
17
+ }
18
+
19
+ if (!path) return obj[part]
20
+ else return _getobj(obj[part], path)
21
+ }
22
+
23
+ /*******************************************************************************
24
+ * XAPIStatement - a convenience class to wrap statement objects
25
+ *
26
+ * This sub-API is supposed to make it easier to author valid xAPI statements
27
+ * by adding constructors and encouraging best practices. All objects in this
28
+ * API are fully JSON-compatible, so anything expecting an xAPI statement can
29
+ * take an improved statement and vice versa.
30
+ *
31
+ * A working knowledge of what exactly the LRS expects is still expected,
32
+ * but it's easier to map an 'I did this' statement to xAPI now.
33
+ *
34
+ * Tech note: All constructors also double as shallow clone functions. E.g.
35
+ *
36
+ * var activity1 = new Activity('A walk in the park');
37
+ * var activity2 = new Activity(activity1);
38
+ * var activity3 = new Activity(stmt_from_lrs.object);
39
+ *
40
+ *******************************************************************************/
41
+
42
+ /*
43
+ * A convenient JSON-compatible xAPI statement wrapper
44
+ * All args are optional, but the statement may not be complete or valid
45
+ * Can also pass an Agent IFI, Verb ID, and an Activity ID in lieu of these args
46
+ * @param {string} [actor] The Agent or Group committing the action described by the statement
47
+ * @param {string} [verb] The Verb for the action described by the statement
48
+ * @param {string} [object] The receiver of the action. An Agent, Group, Activity, SubStatement, or StatementRef
49
+ * @example
50
+ * var stmt = new ADL.XAPIStatement(
51
+ * 'mailto:steve.vergenz.ctr@adlnet.gov',
52
+ * 'http://adlnet.gov/expapi/verbs/launched',
53
+ * 'http://vwf.adlnet.gov/xapi/virtual_world_sandbox'
54
+ * );
55
+ * >> {
56
+ * "actor": {
57
+ * "objectType": "Agent",
58
+ * "mbox": "mailto:steve.vergenz.ctr@adlnet.gov" },
59
+ * "verb": {
60
+ * "id": "http://adlnet.gov/expapi/verbs/launched" },
61
+ * "object": {
62
+ * "objectType": "Activity",
63
+ * "id": "http://vwf.adlnet.gov/xapi/virtual_world_sandbox" },
64
+ * "result": {
65
+ * "An optional property that represents a measured outcome related to the Statement in which it is included."}}
66
+ */
67
+ var XAPIStatement = function (actor, verb, object, context, result) {
68
+ // initialize
69
+
70
+ // if first arg is an xapi statement, parse
71
+ if (actor && actor.actor && actor.verb && actor.object) {
72
+ var stmt = actor
73
+ for (var i in stmt) {
74
+ if (i != 'actor' && i != 'verb' && i != 'object') this[i] = stmt[i]
75
+ }
76
+ actor = stmt.actor
77
+ verb = stmt.verb
78
+ object = stmt.object
79
+ }
80
+
81
+ if (actor) {
82
+ if (actor instanceof Agent) this.actor = actor
83
+ else if (actor.objectType === 'Agent' || !actor.objectType)
84
+ this.actor = new Agent(actor)
85
+ else if (actor.objectType === 'Group') this.actor = new Group(actor)
86
+ } else this.actor = null
87
+
88
+ if (verb) {
89
+ this._setVerb(verb)
90
+ // if (verb instanceof Verb) this.verb = verb
91
+ // else this.verb = new Verb(verb)
92
+ } else this.verb = null
93
+
94
+ // decide what kind of object was passed
95
+ if (object) {
96
+ // if (object.objectType === 'Activity' || !object.objectType) {
97
+ // if (object instanceof Activity) this.object = object
98
+ // else this.object = new Activity(object)
99
+ // } else if (object.objectType === 'Agent') {
100
+ // if (object instanceof Agent) this.object = object
101
+ // else this.object = new Agent(object)
102
+ // } else if (object.objectType === 'Group') {
103
+ // if (object instanceof Group) this.object = object
104
+ // else this.object = new Group(object)
105
+ // } else if (object.objectType === 'StatementRef') {
106
+ // if (object instanceof StatementRef) this.object = object
107
+ // else this.object = new StatementRef(object)
108
+ // } else if (object.objectType === 'SubStatement') {
109
+ // if (object instanceof SubStatement) this.object = object
110
+ // else this.object = new SubStatement(object)
111
+ // } else this.object = null
112
+ this._setObject(object)
113
+ } else this.object = null
114
+
115
+ // add support for result object
116
+ if (result) {
117
+ this.result = result
118
+ }
119
+
120
+ // add support for result context
121
+ if (context) {
122
+ this.context = context
123
+ }
124
+
125
+ this.generateId = function () {
126
+ this.id = ADL.ruuid()
127
+ }
128
+ }
129
+
130
+ XAPIStatement.prototype.toString = function () {
131
+ return (
132
+ this.actor.toString() +
133
+ ' ' +
134
+ this.verb.toString() +
135
+ ' ' +
136
+ this.object.toString() +
137
+ ' ' +
138
+ this.result.toString()
139
+ )
140
+ }
141
+
142
+ XAPIStatement.prototype.isValid = function () {
143
+ return (
144
+ this.actor &&
145
+ this.actor.isValid() &&
146
+ this.verb &&
147
+ this.verb.isValid() &&
148
+ this.object &&
149
+ this.object.isValid() &&
150
+ this.result &&
151
+ this.result.isValid()
152
+ )
153
+ }
154
+
155
+ XAPIStatement.prototype.generateRegistration = function () {
156
+ _getobj(this, 'context').registration = ADL.ruuid()
157
+ }
158
+
159
+ XAPIStatement.prototype.addParentActivity = function (activity) {
160
+ _getobj(this, 'context.contextActivities.parent[]').push(
161
+ new Activity(activity)
162
+ )
163
+ }
164
+
165
+ XAPIStatement.prototype.addGroupingActivity = function (activity) {
166
+ _getobj(this, 'context.contextActivities.grouping[]').push(
167
+ new Activity(activity)
168
+ )
169
+ }
170
+
171
+ XAPIStatement.prototype.addOtherContextActivity = function (activity) {
172
+ _getobj(this, 'context.contextActivities.other[]').push(
173
+ new Activity(activity)
174
+ )
175
+ }
176
+
177
+ ///////////////////////////////////////////////////////////////
178
+ XAPIStatement.prototype._setActor = function (email, name, objectType) {
179
+ let actor = {
180
+ mbox: 'mailto:' + email,
181
+ name: name,
182
+ objectType: ''
183
+ }
184
+ actor.objectType = objectType || 'Agent'
185
+
186
+ this.actor = actor
187
+ }
188
+
189
+ /* helper function to set/change the verb of a statement
190
+ * @Params {String | Object} verb
191
+ *
192
+ */
193
+ XAPIStatement.prototype._setVerb = function (verb) {
194
+ if (verb instanceof Verb) this.verb = verb
195
+ else if (verbs[verb]) this.verb = verbs[verb]
196
+ else this.verb = new Verb(verb)
197
+ }
198
+
199
+ XAPIStatement.prototype._setObject = function (object) {
200
+ if (object.objectType === 'Activity' || !object.objectType) {
201
+ if (object instanceof Activity) this.object = object
202
+ else this.object = new Activity(object)
203
+ } else if (object.objectType === 'Agent') {
204
+ if (object instanceof Agent) this.object = object
205
+ else this.object = new Agent(object)
206
+ } else if (object.objectType === 'Group') {
207
+ if (object instanceof Group) this.object = object
208
+ else this.object = new Group(object)
209
+ } else if (object.objectType === 'StatementRef') {
210
+ if (object instanceof StatementRef) this.object = object
211
+ else this.object = new StatementRef(object)
212
+ } else if (object.objectType === 'SubStatement') {
213
+ if (object instanceof SubStatement) this.object = object
214
+ else this.object = new SubStatement(object)
215
+ } else this.object = null
216
+ }
217
+
218
+ XAPIStatement.prototype._setResultScore = function (
219
+ score,
220
+ scoreScale,
221
+ scoreMin,
222
+ scoreMax
223
+ ) {
224
+ if (!this.result) this.result = {}
225
+ this.result.score = {
226
+ scaled: scoreScale || 1,
227
+ min: scoreMin,
228
+ max: scoreMax,
229
+ raw: score
230
+ }
231
+ }
232
+
233
+ XAPIStatement.prototype._setResultKey = function (key, value) {
234
+ if (!this.result) this.result = {} //define the result key
235
+ //define the extra keys of the result
236
+ if (key == 'success') this.result.success = value
237
+ else if (key == 'response') this.result.response = value
238
+ else if (key == 'duration') this.result.duration = value
239
+ else if (key == 'extensions') this.result.extensions = value
240
+ else if (key == 'completion') this.result.completion = value
241
+ }
242
+
243
+ XAPIStatement.prototype._setContext = function (context) {
244
+ if (typeof context !== 'object') throw 'this not a valid context'
245
+ if (!this.context)
246
+ Object.defineProperty(this, 'context', { value: {}, writable: true })
247
+ this.context = { ...context }
248
+
249
+ // if (key == 'instructor') this.context.instructor = value
250
+ // else if (key == 'contextActivities') this.context.contextActivities = value
251
+ }
252
+
253
+ ///////////////////////////////////////////////////////////////
254
+
255
+ /*
256
+ * Provides an easy constructor for xAPI agent objects
257
+ * @param {string} identifier One of the Inverse Functional Identifiers specified in the spec.
258
+ * That is, an email, a hashed email, an OpenID, or an account object.
259
+ * See (https://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#inversefunctional)
260
+ * @param {string} [name] The natural-language name of the agent
261
+ */
262
+ var Agent = function (identifier, name) {
263
+ this.objectType = 'Agent'
264
+ this.name = name
265
+
266
+ // figure out what type of identifier was given
267
+ if (
268
+ identifier &&
269
+ (identifier.mbox ||
270
+ identifier.mbox_sha1sum ||
271
+ identifier.openid ||
272
+ identifier.account)
273
+ ) {
274
+ for (var i in identifier) {
275
+ this[i] = identifier[i]
276
+ }
277
+ } else if (/^mailto:/.test(identifier)) {
278
+ this.mbox = identifier
279
+ } else if (/^[0-9a-f]{40}$/i.test(identifier)) {
280
+ this.mbox_sha1sum = identifier
281
+ } else if (/^http[s]?:/.test(identifier)) {
282
+ this.openid = identifier
283
+ } else if (identifier && identifier.homePage && identifier.name) {
284
+ this.account = identifier
285
+ }
286
+ }
287
+ Agent.prototype.toString = function () {
288
+ return (
289
+ this.name ||
290
+ this.mbox ||
291
+ this.openid ||
292
+ this.mbox_sha1sum ||
293
+ this.account.name
294
+ )
295
+ }
296
+ Agent.prototype.isValid = function () {
297
+ return (
298
+ this.mbox ||
299
+ this.mbox_sha1sum ||
300
+ this.openid ||
301
+ (this.account.homePage && this.account.name) ||
302
+ (this.objectType === 'Group' && this.member)
303
+ )
304
+ }
305
+
306
+ /*
307
+ * A type of agent, can contain multiple agents
308
+ * @param {string} [identifier] (optional if `members` specified) See Agent.
309
+ * @param {string} [members] An array of Agents describing the membership of the group
310
+ * @param {string} [name] The natural-language name of the agent
311
+ */
312
+ var Group = function (identifier, members, name) {
313
+ Agent.call(this, identifier, name)
314
+ this.member = members
315
+ this.objectType = 'Group'
316
+ }
317
+ Group.prototype = new Agent()
318
+
319
+ /*
320
+ * Really only provides a convenient language map
321
+ * @param {string} id The IRI of the action taken
322
+ * @param {string} [description] An English-language description, or a Language Map
323
+ */
324
+ var Verb = function (id, description) {
325
+ // if passed a verb object then copy and return
326
+ if (id && id.id) {
327
+ for (var i in id) {
328
+ this[i] = id[i]
329
+ }
330
+ return
331
+ }
332
+
333
+ // save id and build language map
334
+ this.id = id
335
+ if (description) {
336
+ if (typeof description === 'string' || description instanceof String) {
337
+ this.display = { 'en-US': description }
338
+ } else {
339
+ this.display = description
340
+ }
341
+ }
342
+ }
343
+ Verb.prototype.toString = function () {
344
+ if (this.display && (this.display['en-US'] || this.display['en']))
345
+ return this.display['en-US'] || this.display['en']
346
+ else return this.id
347
+ }
348
+ Verb.prototype.isValid = function () {
349
+ return this.id
350
+ }
351
+
352
+ /*
353
+ * Describes an object that an agent interacts with
354
+ * @param {string} id The unique activity IRI
355
+ * @param {string} name An English-language identifier for the activity, or a Language Map
356
+ * @param {string} description An English-language description of the activity, or a Language Map
357
+ */
358
+ var Activity = function (id, name, description) {
359
+ // if first arg is activity, copy everything over
360
+ if (id && id.id) {
361
+ var act = id
362
+ for (var i in act) {
363
+ this[i] = act[i]
364
+ }
365
+ return
366
+ }
367
+
368
+ this.objectType = 'Activity'
369
+ this.id = id
370
+ if (name || description) {
371
+ this.definition = {}
372
+
373
+ if (typeof name === 'string' || name instanceof String)
374
+ this.definition.name = { 'en-US': name }
375
+ else if (name) this.definition.name = name
376
+
377
+ if (typeof description === 'string' || description instanceof String)
378
+ this.definition.description = { 'en-US': description }
379
+ else if (description) this.definition.description = description
380
+ }
381
+ }
382
+ Activity.prototype.toString = function () {
383
+ if (
384
+ this.definition &&
385
+ this.definition.name &&
386
+ (this.definition.name['en-US'] || this.definition.name['en'])
387
+ )
388
+ return this.definition.name['en-US'] || this.definition.name['en']
389
+ else return this.id
390
+ }
391
+ Activity.prototype.isValid = function () {
392
+ return this.id && (!this.objectType || this.objectType === 'Activity')
393
+ }
394
+
395
+ /*
396
+ * An object that refers to a separate statement
397
+ * @param {string} id The UUID of another xAPI statement
398
+ */
399
+ var StatementRef = function (id) {
400
+ if (id && id.id) {
401
+ for (var i in id) {
402
+ this[i] = id[i]
403
+ }
404
+ } else {
405
+ this.objectType = 'StatementRef'
406
+ this.id = id
407
+ }
408
+ }
409
+ StatementRef.prototype.toString = function () {
410
+ return 'statement(' + this.id + ')'
411
+ }
412
+ StatementRef.prototype.isValid = function () {
413
+ return this.id && this.objectType && this.objectType === 'StatementRef'
414
+ }
415
+
416
+ /*
417
+ * A self-contained statement as the object of another statement
418
+ * See XAPIStatement for constructor details
419
+ * @param {string} actor The Agent or Group committing the action described by the statement
420
+ * @param {string} verb The Verb for the action described by the statement
421
+ * @param {string} object The receiver of the action. An Agent, Group, Activity, or StatementRef
422
+ */
423
+ var SubStatement = function (actor, verb, object) {
424
+ XAPIStatement.call(this, actor, verb, object)
425
+ this.objectType = 'SubStatement'
426
+
427
+ delete this.id
428
+ delete this.stored
429
+ delete this.version
430
+ delete this.authority
431
+ }
432
+ SubStatement.prototype = new XAPIStatement()
433
+ SubStatement.prototype.toString = function () {
434
+ return '"' + SubStatement.prototype.prototype.toString.call(this) + '"'
435
+ }
436
+
437
+ XAPIStatement.Agent = Agent
438
+ XAPIStatement.Group = Group
439
+ XAPIStatement.Verb = Verb
440
+ XAPIStatement.Activity = Activity
441
+ XAPIStatement.StatementRef = StatementRef
442
+ XAPIStatement.SubStatement = SubStatement
443
+ ADL.XAPIStatement = XAPIStatement
444
+ }