fcad-core-dragon 2.0.1-beta.1 → 2.0.2-beta.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 (90) hide show
  1. package/.editorconfig +33 -33
  2. package/.eslintignore +29 -29
  3. package/.eslintrc.cjs +81 -81
  4. package/CHANGELOG +20 -0
  5. package/bk.scss +117 -117
  6. package/package.json +1 -1
  7. package/src/$locales/en.json +18 -4
  8. package/src/$locales/fr.json +17 -3
  9. package/src/assets/data/onboardingMessages.json +47 -47
  10. package/src/components/AppBase.vue +36 -341
  11. package/src/components/AppBaseErrorDisplay.vue +438 -438
  12. package/src/components/AppBaseFlipCard.vue +84 -84
  13. package/src/components/AppBaseModule.vue +16 -21
  14. package/src/components/AppBasePage.vue +45 -14
  15. package/src/components/AppBasePopover.vue +41 -41
  16. package/src/components/AppBaseSkeleton.vue +45 -0
  17. package/src/components/AppCompAudio.vue +12 -3
  18. package/src/components/AppCompButtonProgress.vue +13 -2
  19. package/src/components/AppCompCarousel.vue +14 -6
  20. package/src/components/AppCompInputCheckBoxNx.vue +324 -0
  21. package/src/components/AppCompInputDropdownNx.vue +295 -0
  22. package/src/components/AppCompInputRadioNx.vue +264 -0
  23. package/src/components/AppCompInputTextNx.vue +148 -0
  24. package/src/components/AppCompInputTextTableNx.vue +198 -0
  25. package/src/components/AppCompInputTextToFillDropdownNx.vue +291 -0
  26. package/src/components/AppCompInputTextToFillNx.vue +277 -0
  27. package/src/components/AppCompJauge.vue +81 -74
  28. package/src/components/AppCompMenu.vue +7 -14
  29. package/src/components/AppCompMenuItem.vue +7 -5
  30. package/src/components/AppCompNavigation.vue +21 -21
  31. package/src/components/AppCompNoteCall.vue +1 -0
  32. package/src/components/AppCompNoteCredit.vue +2 -1
  33. package/src/components/AppCompPlayBarNext.vue +94 -41
  34. package/src/components/AppCompPlayBarProgress.vue +82 -82
  35. package/src/components/AppCompPopUpNext.vue +6 -6
  36. package/src/components/AppCompQuizNx.vue +500 -0
  37. package/src/components/AppCompQuizRecall.vue +113 -66
  38. package/src/components/AppCompSettingsMenu.vue +172 -172
  39. package/src/components/AppCompTableOfContent.vue +55 -13
  40. package/src/components/AppCompVideoPlayer.vue +1 -1
  41. package/src/components/AppCompViewDisplay.vue +6 -6
  42. package/src/composables/useQuiz.js +89 -206
  43. package/src/directives/nvdaFix.js +53 -0
  44. package/src/externalComps/ModuleView.vue +22 -22
  45. package/src/externalComps/SummaryView.vue +91 -91
  46. package/src/main.js +227 -30
  47. package/src/mixins/$mediaMixins.js +809 -819
  48. package/src/module/stores/appStore.js +29 -11
  49. package/src/module/xapi/Crypto/Hasher.js +241 -241
  50. package/src/module/xapi/Crypto/WordArray.js +278 -278
  51. package/src/module/xapi/Crypto/algorithms/BufferedBlockAlgorithm.js +103 -103
  52. package/src/module/xapi/Crypto/algorithms/C_algo.js +315 -315
  53. package/src/module/xapi/Crypto/algorithms/HMAC.js +9 -9
  54. package/src/module/xapi/Crypto/algorithms/SHA1.js +9 -9
  55. package/src/module/xapi/Crypto/encoders/Base.js +105 -105
  56. package/src/module/xapi/Crypto/encoders/Base64.js +99 -99
  57. package/src/module/xapi/Crypto/encoders/Hex.js +61 -61
  58. package/src/module/xapi/Crypto/encoders/Latin1.js +61 -61
  59. package/src/module/xapi/Crypto/encoders/Utf8.js +45 -45
  60. package/src/module/xapi/Crypto/index.js +53 -53
  61. package/src/module/xapi/Statement/activity.js +47 -47
  62. package/src/module/xapi/Statement/agent.js +55 -55
  63. package/src/module/xapi/Statement/group.js +26 -26
  64. package/src/module/xapi/Statement/index.js +259 -259
  65. package/src/module/xapi/Statement/statement.js +253 -253
  66. package/src/module/xapi/Statement/statementRef.js +23 -23
  67. package/src/module/xapi/Statement/substatement.js +22 -22
  68. package/src/module/xapi/Statement/verb.js +36 -36
  69. package/src/module/xapi/activitytypes.js +17 -17
  70. package/src/module/xapi/utils.js +167 -167
  71. package/src/module/xapi/verbs.js +294 -294
  72. package/src/module/xapi/xapiStatement.js +444 -444
  73. package/src/plugins/bus.js +8 -8
  74. package/src/plugins/gsap.js +14 -14
  75. package/src/plugins/i18n.js +44 -44
  76. package/src/plugins/idb.js +1 -1
  77. package/src/plugins/save.js +37 -37
  78. package/src/plugins/scorm.js +287 -287
  79. package/src/plugins/xapi.js +11 -11
  80. package/src/public/index.html +33 -33
  81. package/src/shared/generalfuncs.js +344 -210
  82. package/src/shared/validators.js +308 -234
  83. package/src/components/AppCompInputCheckBoxNext.vue +0 -205
  84. package/src/components/AppCompInputDropdownNext.vue +0 -201
  85. package/src/components/AppCompInputRadioNext.vue +0 -158
  86. package/src/components/AppCompInputTextNext.vue +0 -124
  87. package/src/components/AppCompInputTextTableNext.vue +0 -142
  88. package/src/components/AppCompInputTextToFillDropdownNext.vue +0 -238
  89. package/src/components/AppCompInputTextToFillNext.vue +0 -171
  90. package/src/components/AppCompQuizNext.vue +0 -2908
@@ -50,9 +50,10 @@ export const useAppStore = defineStore('$appStore', {
50
50
  compStatusTracker: [],
51
51
  dataFromServer: null,
52
52
  errMenuSetting: null,
53
- endPopUp: false
54
- //_allFiles: [],
55
- //allModuleRoutes: null
53
+ endPopUp: false,
54
+ userDataLoaded: false,
55
+ lessonPosition: [],
56
+ completedState: {}
56
57
  }
57
58
  },
58
59
  //=======================GETTERS
@@ -80,6 +81,9 @@ export const useAppStore = defineStore('$appStore', {
80
81
  return state.mediaMuted
81
82
  },
82
83
 
84
+ getUserDataStatus: (state) => {
85
+ return state.userDataLoaded
86
+ },
83
87
  /**
84
88
  * @description: Check if automatic video playback is enabled in application settings
85
89
  */
@@ -363,6 +367,7 @@ export const useAppStore = defineStore('$appStore', {
363
367
  return (activity = null, id = null) => {
364
368
  if (!activity || !id) return null
365
369
  const allInteraction = this.getUserInteraction
370
+
366
371
  if (!allInteraction[activity] || !allInteraction[activity][id])
367
372
  return {}
368
373
 
@@ -381,7 +386,7 @@ export const useAppStore = defineStore('$appStore', {
381
386
  let allStates
382
387
  let temp = []
383
388
 
384
- if (state.userMetaData[aKey]) {
389
+ if (state.userMetaData && state.userMetaData[aKey]) {
385
390
  const activity = Object.entries(state.userMetaData[aKey])
386
391
 
387
392
  // get all the completed acitivities
@@ -612,6 +617,13 @@ export const useAppStore = defineStore('$appStore', {
612
617
 
613
618
  getEndPopUp: (state) => {
614
619
  return state.endPopUp
620
+ },
621
+
622
+ getLessonPosition(state) {
623
+ return state.lessonPosition
624
+ },
625
+ getCompletionState(state) {
626
+ return state.completedState
615
627
  }
616
628
  },
617
629
  //=======================ACTIONS
@@ -647,6 +659,12 @@ export const useAppStore = defineStore('$appStore', {
647
659
  setApplicationSettings(settings) {
648
660
  this.applicationSettings = settings
649
661
  },
662
+ setLessonPosition(newData) {
663
+ this.lessonPosition = newData
664
+ },
665
+ setCompletionState(newData) {
666
+ this.completedState = newData
667
+ },
650
668
 
651
669
  setMediaVolume(volume) {
652
670
  this.mediaVolume = volume
@@ -672,7 +690,7 @@ export const useAppStore = defineStore('$appStore', {
672
690
  },
673
691
 
674
692
  /* set/update the Application configuration*/
675
- async setAppConfigs(data) {
693
+ async initializeApp(data) {
676
694
  this.appConfigs = data
677
695
  const {
678
696
  id,
@@ -904,12 +922,12 @@ export const useAppStore = defineStore('$appStore', {
904
922
  this.sideBIsOpen = data
905
923
  },
906
924
 
907
- async updateDataFetchFromServer(data) {
908
- if (!data || data.constructor !== Object) return
909
- Object.keys(data).forEach((k) => {
910
- this.dataFromServer = { ...this.dataFromServer, [k]: data[k] }
911
- })
912
- },
925
+ // async updateDataFetchFromServer(data) {
926
+ // if (!data || data.constructor !== Object) return
927
+ // Object.keys(data).forEach((k) => {
928
+ // this.dataFromServer = { ...this.dataFromServer, [k]: data[k] }
929
+ // })
930
+ // },
913
931
 
914
932
  updatePreviousActivity(data) {
915
933
  this.prevActivity = data
@@ -1,241 +1,241 @@
1
- import { Base } from './encoders/Base'
2
- import { C_algo } from './algorithms/C_algo'
3
- import { BufferedBlockAlgorithm } from './algorithms/BufferedBlockAlgorithm'
4
-
5
- /**
6
- * Abstract hasher template.
7
- * @property {number} blockSize The number of 32-bit words this hasher operates on. Default: 16 (512 bits)
8
- */
9
- export const Hasher = BufferedBlockAlgorithm.extend({
10
- /**
11
- * Configuration options.
12
- */
13
- cfg: Base.extend(),
14
-
15
- /**
16
- * Initializes a newly created hasher.
17
- *
18
- * @param {Object} cfg (Optional) The configuration options to use for this hash computation.
19
- *
20
- * @example
21
- *
22
- * var hasher = CryptoJS.algo.SHA256.create();
23
- */
24
- init: function (cfg) {
25
- // Apply config defaults
26
- this.cfg = this.cfg.extend(cfg)
27
-
28
- // Set initial values
29
- this.reset()
30
- },
31
-
32
- /**
33
- * Resets this hasher to its initial state.
34
- *
35
- * @example
36
- *
37
- * hasher.reset();
38
- */
39
- reset: function () {
40
- // Reset data buffer
41
- BufferedBlockAlgorithm.reset.call(this)
42
-
43
- // Perform concrete-hasher logic
44
- this._doReset()
45
- },
46
-
47
- /**
48
- * Updates this hasher with a message.
49
- *
50
- * @param {WordArray|string} messageUpdate The message to append.
51
- *
52
- * @return {Hasher} This hasher.
53
- *
54
- * @example
55
- *
56
- * hasher.update('message');
57
- * hasher.update(wordArray);
58
- */
59
- update: function (messageUpdate) {
60
- // Append
61
- this._append(messageUpdate)
62
-
63
- // Update the hash
64
- this._process()
65
-
66
- // Chainable
67
- return this
68
- },
69
-
70
- /**
71
- * Finalizes the hash computation.
72
- * Note that the finalize operation is effectively a destructive, read-once operation.
73
- *
74
- * @param {WordArray|string} messageUpdate (Optional) A final message update.
75
- *
76
- * @return {WordArray} The hash.
77
- *
78
- * @example
79
- *
80
- * var hash = hasher.finalize();
81
- * var hash = hasher.finalize('message');
82
- * var hash = hasher.finalize(wordArray);
83
- */
84
- finalize: function (messageUpdate) {
85
- // Final message update
86
- if (messageUpdate) {
87
- this._append(messageUpdate)
88
- }
89
-
90
- // Perform concrete-hasher logic
91
- var hash = this._doFinalize()
92
-
93
- return hash
94
- },
95
-
96
- blockSize: 512 / 32,
97
-
98
- /**
99
- * Creates a shortcut function to a hasher's object interface.
100
- *
101
- * @param {Hasher} hasher The hasher to create a helper for.
102
- *
103
- * @return {Function} The shortcut function.
104
- *
105
- * @static
106
- *
107
- * @example
108
- *
109
- * var SHA256 = CryptoJS.lib.Hasher._createHelper(CryptoJS.algo.SHA256);
110
- */
111
- _createHelper: function (hasher) {
112
- return function (message, cfg) {
113
- return new hasher.init(cfg).finalize(message)
114
- }
115
- },
116
-
117
- /**
118
- * Creates a shortcut function to the HMAC's object interface.
119
- *
120
- * @param {Hasher} hasher The hasher to use in this HMAC helper.
121
- *
122
- * @return {Function} The shortcut function.
123
- *
124
- * @static
125
- *
126
- * @example
127
- *
128
- * var HmacSHA256 = CryptoJS.lib.Hasher._createHmacHelper(CryptoJS.algo.SHA256);
129
- */
130
- _createHmacHelper: function (hasher) {
131
- return function (message, key) {
132
- return new C_algo().HMAC.init(hasher, key).finalize(message)
133
- }
134
- }
135
- })
136
-
137
- // export const Hasher =BufferedBlockAlgorithm.extend({
138
- // C_lib(this)
139
- // return {
140
- // /**
141
- // * Configuration options.
142
- // */
143
- // cfg: Base.extend(),
144
- // blockSize: 512 / 32,
145
- // /**
146
- // * Initializes a newly created hasher.
147
- // * @param {Object} cfg (Optional) The configuration options to use for this hash computation.
148
- // * @example
149
- // * var hasher = CryptoJS.algo.SHA256.create();
150
- // */
151
- // init: function(cfg) {
152
- // // Apply config defaults
153
- // this.cfg = this.cfg.extend(cfg)
154
-
155
- // // Set initial values
156
- // this.reset()
157
- // },
158
-
159
- // /**
160
- // * Resets this hasher to its initial state.
161
- // * @example
162
- // * hasher.reset();
163
- // */
164
- // reset: function() {
165
- // // Reset data buffer
166
- // BufferedBlockAlgorithm.reset.call(this)
167
-
168
- // // Perform concrete-hasher logic
169
- // this._doReset()
170
- // },
171
-
172
- // /**
173
- // * Updates this hasher with a message.
174
- // * @param {WordArray|string} messageUpdate The message to append.
175
- // * @return {Hasher} This hasher.
176
- // * @example
177
- // * hasher.update('message');
178
- // * hasher.update(wordArray);
179
- // */
180
- // update: function(messageUpdate) {
181
- // // Append
182
- // this._append(messageUpdate)
183
-
184
- // // Update the hash
185
- // this._process()
186
-
187
- // // Chainable
188
- // return this
189
- // },
190
-
191
- // /**
192
- // * Finalizes the hash computation.
193
- // * Note that the finalize operation is effectively a destructive, read-once operation.
194
- // * @param {WordArray|string} messageUpdate (Optional) A final message update.
195
- // * @return {WordArray} The hash.
196
- // * @example
197
- // * var hash = hasher.finalize();
198
- // * var hash = hasher.finalize('message');
199
- // * var hash = hasher.finalize(wordArray);
200
- // */
201
- // finalize: function(messageUpdate) {
202
- // // Final message update
203
- // if (messageUpdate) {
204
- // this._append(messageUpdate)
205
- // }
206
-
207
- // // Perform concrete-hasher logic
208
- // var hash = this._doFinalize()
209
-
210
- // return hash
211
- // },
212
-
213
- // /**
214
- // * Creates a shortcut function to a hasher's object interface.
215
- // * @param {Hasher} hasher The hasher to create a helper for.
216
- // * @return {Function} The shortcut function.
217
- // * @static
218
- // * @example
219
- // * var SHA256 = CryptoJS.lib.Hasher._createHelper(CryptoJS.algo.SHA256);
220
- // */
221
- // _createHelper: function(hasher) {
222
- // return function(message, cfg) {
223
- // return new hasher.init(cfg).finalize(message)
224
- // }
225
- // },
226
-
227
- // /**
228
- // * Creates a shortcut function to the HMAC's object interface.
229
- // * @param {Hasher} hasher The hasher to use in this HMAC helper.
230
- // * @return {Function} The shortcut function.
231
- // * @static
232
- // * @example
233
- // * var HmacSHA256 = CryptoJS.lib.Hasher._createHmacHelper(CryptoJS.algo.SHA256);
234
- // */
235
- // _createHmacHelper: function(hasher) {
236
- // return function(message, key) {
237
- // return new C_lib.algo.HMAC.init(hasher, key).finalize(message)
238
- // }
239
- // }
240
- // }
241
- // })
1
+ import { Base } from './encoders/Base'
2
+ import { C_algo } from './algorithms/C_algo'
3
+ import { BufferedBlockAlgorithm } from './algorithms/BufferedBlockAlgorithm'
4
+
5
+ /**
6
+ * Abstract hasher template.
7
+ * @property {number} blockSize The number of 32-bit words this hasher operates on. Default: 16 (512 bits)
8
+ */
9
+ export const Hasher = BufferedBlockAlgorithm.extend({
10
+ /**
11
+ * Configuration options.
12
+ */
13
+ cfg: Base.extend(),
14
+
15
+ /**
16
+ * Initializes a newly created hasher.
17
+ *
18
+ * @param {Object} cfg (Optional) The configuration options to use for this hash computation.
19
+ *
20
+ * @example
21
+ *
22
+ * var hasher = CryptoJS.algo.SHA256.create();
23
+ */
24
+ init: function (cfg) {
25
+ // Apply config defaults
26
+ this.cfg = this.cfg.extend(cfg)
27
+
28
+ // Set initial values
29
+ this.reset()
30
+ },
31
+
32
+ /**
33
+ * Resets this hasher to its initial state.
34
+ *
35
+ * @example
36
+ *
37
+ * hasher.reset();
38
+ */
39
+ reset: function () {
40
+ // Reset data buffer
41
+ BufferedBlockAlgorithm.reset.call(this)
42
+
43
+ // Perform concrete-hasher logic
44
+ this._doReset()
45
+ },
46
+
47
+ /**
48
+ * Updates this hasher with a message.
49
+ *
50
+ * @param {WordArray|string} messageUpdate The message to append.
51
+ *
52
+ * @return {Hasher} This hasher.
53
+ *
54
+ * @example
55
+ *
56
+ * hasher.update('message');
57
+ * hasher.update(wordArray);
58
+ */
59
+ update: function (messageUpdate) {
60
+ // Append
61
+ this._append(messageUpdate)
62
+
63
+ // Update the hash
64
+ this._process()
65
+
66
+ // Chainable
67
+ return this
68
+ },
69
+
70
+ /**
71
+ * Finalizes the hash computation.
72
+ * Note that the finalize operation is effectively a destructive, read-once operation.
73
+ *
74
+ * @param {WordArray|string} messageUpdate (Optional) A final message update.
75
+ *
76
+ * @return {WordArray} The hash.
77
+ *
78
+ * @example
79
+ *
80
+ * var hash = hasher.finalize();
81
+ * var hash = hasher.finalize('message');
82
+ * var hash = hasher.finalize(wordArray);
83
+ */
84
+ finalize: function (messageUpdate) {
85
+ // Final message update
86
+ if (messageUpdate) {
87
+ this._append(messageUpdate)
88
+ }
89
+
90
+ // Perform concrete-hasher logic
91
+ var hash = this._doFinalize()
92
+
93
+ return hash
94
+ },
95
+
96
+ blockSize: 512 / 32,
97
+
98
+ /**
99
+ * Creates a shortcut function to a hasher's object interface.
100
+ *
101
+ * @param {Hasher} hasher The hasher to create a helper for.
102
+ *
103
+ * @return {Function} The shortcut function.
104
+ *
105
+ * @static
106
+ *
107
+ * @example
108
+ *
109
+ * var SHA256 = CryptoJS.lib.Hasher._createHelper(CryptoJS.algo.SHA256);
110
+ */
111
+ _createHelper: function (hasher) {
112
+ return function (message, cfg) {
113
+ return new hasher.init(cfg).finalize(message)
114
+ }
115
+ },
116
+
117
+ /**
118
+ * Creates a shortcut function to the HMAC's object interface.
119
+ *
120
+ * @param {Hasher} hasher The hasher to use in this HMAC helper.
121
+ *
122
+ * @return {Function} The shortcut function.
123
+ *
124
+ * @static
125
+ *
126
+ * @example
127
+ *
128
+ * var HmacSHA256 = CryptoJS.lib.Hasher._createHmacHelper(CryptoJS.algo.SHA256);
129
+ */
130
+ _createHmacHelper: function (hasher) {
131
+ return function (message, key) {
132
+ return new C_algo().HMAC.init(hasher, key).finalize(message)
133
+ }
134
+ }
135
+ })
136
+
137
+ // export const Hasher =BufferedBlockAlgorithm.extend({
138
+ // C_lib(this)
139
+ // return {
140
+ // /**
141
+ // * Configuration options.
142
+ // */
143
+ // cfg: Base.extend(),
144
+ // blockSize: 512 / 32,
145
+ // /**
146
+ // * Initializes a newly created hasher.
147
+ // * @param {Object} cfg (Optional) The configuration options to use for this hash computation.
148
+ // * @example
149
+ // * var hasher = CryptoJS.algo.SHA256.create();
150
+ // */
151
+ // init: function(cfg) {
152
+ // // Apply config defaults
153
+ // this.cfg = this.cfg.extend(cfg)
154
+
155
+ // // Set initial values
156
+ // this.reset()
157
+ // },
158
+
159
+ // /**
160
+ // * Resets this hasher to its initial state.
161
+ // * @example
162
+ // * hasher.reset();
163
+ // */
164
+ // reset: function() {
165
+ // // Reset data buffer
166
+ // BufferedBlockAlgorithm.reset.call(this)
167
+
168
+ // // Perform concrete-hasher logic
169
+ // this._doReset()
170
+ // },
171
+
172
+ // /**
173
+ // * Updates this hasher with a message.
174
+ // * @param {WordArray|string} messageUpdate The message to append.
175
+ // * @return {Hasher} This hasher.
176
+ // * @example
177
+ // * hasher.update('message');
178
+ // * hasher.update(wordArray);
179
+ // */
180
+ // update: function(messageUpdate) {
181
+ // // Append
182
+ // this._append(messageUpdate)
183
+
184
+ // // Update the hash
185
+ // this._process()
186
+
187
+ // // Chainable
188
+ // return this
189
+ // },
190
+
191
+ // /**
192
+ // * Finalizes the hash computation.
193
+ // * Note that the finalize operation is effectively a destructive, read-once operation.
194
+ // * @param {WordArray|string} messageUpdate (Optional) A final message update.
195
+ // * @return {WordArray} The hash.
196
+ // * @example
197
+ // * var hash = hasher.finalize();
198
+ // * var hash = hasher.finalize('message');
199
+ // * var hash = hasher.finalize(wordArray);
200
+ // */
201
+ // finalize: function(messageUpdate) {
202
+ // // Final message update
203
+ // if (messageUpdate) {
204
+ // this._append(messageUpdate)
205
+ // }
206
+
207
+ // // Perform concrete-hasher logic
208
+ // var hash = this._doFinalize()
209
+
210
+ // return hash
211
+ // },
212
+
213
+ // /**
214
+ // * Creates a shortcut function to a hasher's object interface.
215
+ // * @param {Hasher} hasher The hasher to create a helper for.
216
+ // * @return {Function} The shortcut function.
217
+ // * @static
218
+ // * @example
219
+ // * var SHA256 = CryptoJS.lib.Hasher._createHelper(CryptoJS.algo.SHA256);
220
+ // */
221
+ // _createHelper: function(hasher) {
222
+ // return function(message, cfg) {
223
+ // return new hasher.init(cfg).finalize(message)
224
+ // }
225
+ // },
226
+
227
+ // /**
228
+ // * Creates a shortcut function to the HMAC's object interface.
229
+ // * @param {Hasher} hasher The hasher to use in this HMAC helper.
230
+ // * @return {Function} The shortcut function.
231
+ // * @static
232
+ // * @example
233
+ // * var HmacSHA256 = CryptoJS.lib.Hasher._createHmacHelper(CryptoJS.algo.SHA256);
234
+ // */
235
+ // _createHmacHelper: function(hasher) {
236
+ // return function(message, key) {
237
+ // return new C_lib.algo.HMAC.init(hasher, key).finalize(message)
238
+ // }
239
+ // }
240
+ // }
241
+ // })