@01-edu/shared 2.0.4 → 2.0.6
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/dist/attrs-defs.js +1 -0
- package/dist/attrs.js +1 -0
- package/dist/bin/check-definitions.js +3 -0
- package/dist/chunk-BLXMKMNK.js +1 -0
- package/dist/chunk-FQWECXED.js +1 -0
- package/dist/chunk-IF63VBJO.js +1 -0
- package/dist/chunk-K5Z4W5GV.js +1 -0
- package/dist/chunk-MV3DQ3PZ.js +1 -0
- package/dist/chunk-NR2KVFFU.js +1 -0
- package/dist/chunk-T2KIY67K.js +1 -0
- package/dist/chunk-YJMXNRLI.js +1 -0
- package/dist/chunk-ZI7IBRHE.js +1 -0
- package/dist/definitions-checker.js +1 -0
- package/dist/event-utils.js +1 -0
- package/dist/games-utils.js +1 -0
- package/dist/graph.js +1 -0
- package/dist/hasura-core.js +1 -0
- package/dist/hasura-model.js +34 -0
- package/dist/hasura-prepare.js +1 -0
- package/dist/modular-steps-utils.js +1 -0
- package/dist/object-structure.js +1 -0
- package/dist/onboarding.js +1 -0
- package/dist/path.js +1 -0
- package/dist/qa-utils.js +1 -0
- package/dist/score.js +1 -0
- package/dist/skill-definitions.js +1 -0
- package/dist/toolbox.js +1 -0
- package/package.json +23 -5
- package/attrs-defs.js +0 -4273
- package/attrs.js +0 -423
- package/bin/check-definitions.js +0 -74
- package/definitions-checker.js +0 -233
- package/event-utils.js +0 -58
- package/graph.js +0 -96
- package/languages.js +0 -147
- package/object-structure.ts +0 -60
- package/onboarding.js +0 -25
- package/path.js +0 -73
- package/programming-languages.js +0 -21
- package/score.js +0 -80
- package/skill-definitions.js +0 -359
- package/toolbox.js +0 -532
package/programming-languages.js
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
// because of the nature of esbuild we have to put the import string hard coded
|
|
2
|
-
export const langTypeInfo = {
|
|
3
|
-
go: { lang: 'go', load: () => import('@codemirror/lang-go') },
|
|
4
|
-
bash: { lang: 'bash', load: () => import('@fig/lezer-bash') },
|
|
5
|
-
sh: { lang: 'shell', load: () => import('@fig/lezer-bash') },
|
|
6
|
-
// The `label` is used for the UI (StatusBar) so it still shows "dart" instead of "javascript"
|
|
7
|
-
dart: {
|
|
8
|
-
label: 'dart',
|
|
9
|
-
lang: 'javascript',
|
|
10
|
-
load: () => import('@codemirror/lang-javascript'),
|
|
11
|
-
},
|
|
12
|
-
css: { lang: 'css', load: () => import('@codemirror/lang-css') },
|
|
13
|
-
html: { lang: 'html', load: () => import('@codemirror/lang-html') },
|
|
14
|
-
js: { lang: 'javascript', load: () => import('@codemirror/lang-javascript') },
|
|
15
|
-
md: { lang: 'markdown', load: () => import('@codemirror/lang-markdown') },
|
|
16
|
-
rs: { lang: 'rust', load: () => import('@codemirror/lang-rust') },
|
|
17
|
-
py: { lang: 'python', load: () => import('@codemirror/lang-python') },
|
|
18
|
-
java: { lang: 'java', load: () => import('@codemirror/lang-java') },
|
|
19
|
-
json: { lang: 'json', load: () => import('@codemirror/lang-json') },
|
|
20
|
-
}
|
|
21
|
-
export const supportedLang = new Set(Object.keys(langTypeInfo))
|
package/score.js
DELETED
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
const levelPoints = 5
|
|
2
|
-
export const gamesScoring = {
|
|
3
|
-
memory: {
|
|
4
|
-
maxLevel: 22,
|
|
5
|
-
minRatio: 1,
|
|
6
|
-
freeAttempts: 1000,
|
|
7
|
-
maxAttempts: 1000,
|
|
8
|
-
shouldFailUnderScore: 30,
|
|
9
|
-
shouldFailUnderLevel: 7,
|
|
10
|
-
shouldSucceedFromScore: 60,
|
|
11
|
-
shouldSucceedFromLevel: 15,
|
|
12
|
-
},
|
|
13
|
-
zzle: {
|
|
14
|
-
maxLevel: 18,
|
|
15
|
-
minRatio: 1,
|
|
16
|
-
freeAttempts: 1000,
|
|
17
|
-
maxAttempts: 1000,
|
|
18
|
-
shouldFailUnderScore: 20,
|
|
19
|
-
shouldFailUnderLevel: 3,
|
|
20
|
-
shouldSucceedFromScore: 50,
|
|
21
|
-
shouldSucceedFromLevel: 10,
|
|
22
|
-
},
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
for (const game of Object.values(gamesScoring)) {
|
|
26
|
-
game.levels = [...Array(game.maxLevel + 50).keys()].map(index => ({
|
|
27
|
-
maxScore: ((index + 1) / 15 + 1) * levelPoints,
|
|
28
|
-
}))
|
|
29
|
-
game.maxScore = game.levels
|
|
30
|
-
.slice(0, game.maxLevel)
|
|
31
|
-
.reduce((acc, level) => acc + level.maxScore, 0)
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
const projectValue = (count, max, minRatio, free) => {
|
|
35
|
-
const dist = 1 - minRatio
|
|
36
|
-
const diff = max - (count - free)
|
|
37
|
-
|
|
38
|
-
if (count <= free || minRatio === 1) return 1
|
|
39
|
-
if (diff < 1) return minRatio
|
|
40
|
-
return (diff / max) * dist + minRatio
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
const getLevelRatio = (gameName, levelAttempts) => {
|
|
44
|
-
const { minRatio, freeAttempts, maxAttempts } = gamesScoring[gameName]
|
|
45
|
-
|
|
46
|
-
return projectValue(levelAttempts, maxAttempts, minRatio, freeAttempts)
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
export const getLevelScore = (gameName, levelAttempts, levelNumber) =>
|
|
50
|
-
// TODO: reduce level score differences
|
|
51
|
-
(levelNumber / 15 + 1) * levelPoints * getLevelRatio(gameName, levelAttempts)
|
|
52
|
-
|
|
53
|
-
export const getLevelMaxPoints = (levelIndex, gameName) =>
|
|
54
|
-
gamesScoring[gameName].levels[levelIndex].maxScore
|
|
55
|
-
|
|
56
|
-
export const getLevelsScore = (gameName, results) =>
|
|
57
|
-
results
|
|
58
|
-
.map((level, levelIndex) =>
|
|
59
|
-
getLevelScore(gameName, level.attempts, levelIndex + 1),
|
|
60
|
-
)
|
|
61
|
-
.reduce((a, b) => a + b, 0)
|
|
62
|
-
|
|
63
|
-
export const getGameScores = (gameName, gamePoints, results) => {
|
|
64
|
-
const totalLevelsScore = getLevelsScore(gameName, results)
|
|
65
|
-
const ratio = totalLevelsScore / gamesScoring[gameName].maxScore
|
|
66
|
-
|
|
67
|
-
return {
|
|
68
|
-
ratio,
|
|
69
|
-
percent: ratio * 100, // TODO: represent the percentage of level done
|
|
70
|
-
points: gamePoints * ratio,
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
export const getGlobalScore = games => {
|
|
75
|
-
const totalScoreInPercent = games
|
|
76
|
-
.map(game => getGameScores(game.name, game.points, game.results).percent)
|
|
77
|
-
.reduce((a, b) => a + b, 0)
|
|
78
|
-
|
|
79
|
-
return totalScoreInPercent / games.length
|
|
80
|
-
}
|
package/skill-definitions.js
DELETED
|
@@ -1,359 +0,0 @@
|
|
|
1
|
-
export const skillsSet = {
|
|
2
|
-
// technical skills
|
|
3
|
-
prog: {
|
|
4
|
-
name: 'Elementary programming',
|
|
5
|
-
description: 'Basics of computer programming',
|
|
6
|
-
type: 'technical',
|
|
7
|
-
abbreviation: 'prog-1',
|
|
8
|
-
},
|
|
9
|
-
'intermediate-prog': {
|
|
10
|
-
name: 'Intermediate programming',
|
|
11
|
-
description: 'Intermediate notions of computer programming',
|
|
12
|
-
type: 'technical',
|
|
13
|
-
abbreviation: 'prog-2',
|
|
14
|
-
},
|
|
15
|
-
'advanced-prog': {
|
|
16
|
-
name: 'Advanced programming',
|
|
17
|
-
description: 'Advanced notions of computer programming',
|
|
18
|
-
type: 'technical',
|
|
19
|
-
abbreviation: 'prog-3',
|
|
20
|
-
},
|
|
21
|
-
algo: {
|
|
22
|
-
name: 'Elementary algorithms',
|
|
23
|
-
description: 'Problem-solving, algorithm design',
|
|
24
|
-
type: 'technical',
|
|
25
|
-
},
|
|
26
|
-
'sys-admin': {
|
|
27
|
-
name: 'System administration',
|
|
28
|
-
description: 'System administration, dev ops',
|
|
29
|
-
type: 'technical',
|
|
30
|
-
abbreviation: 'devops',
|
|
31
|
-
},
|
|
32
|
-
'front-end': {
|
|
33
|
-
name: 'Front-end',
|
|
34
|
-
description: 'Front-end technologies',
|
|
35
|
-
type: 'technical',
|
|
36
|
-
abbreviation: 'front',
|
|
37
|
-
},
|
|
38
|
-
'back-end': {
|
|
39
|
-
name: 'Back-end',
|
|
40
|
-
description: 'Back-end technologies',
|
|
41
|
-
type: 'technical',
|
|
42
|
-
abbreviation: 'back',
|
|
43
|
-
},
|
|
44
|
-
stats: {
|
|
45
|
-
name: 'Statistics',
|
|
46
|
-
description: 'Data analysis, interpretation',
|
|
47
|
-
type: 'technical',
|
|
48
|
-
},
|
|
49
|
-
ai: {
|
|
50
|
-
name: 'AI',
|
|
51
|
-
description: 'Artificial intelligence, machine learning',
|
|
52
|
-
type: 'technical',
|
|
53
|
-
},
|
|
54
|
-
game: {
|
|
55
|
-
name: 'Game programming',
|
|
56
|
-
description: 'Game programming',
|
|
57
|
-
type: 'technical',
|
|
58
|
-
},
|
|
59
|
-
blockchain: {
|
|
60
|
-
name: 'Blockchain',
|
|
61
|
-
description: 'Blockchain',
|
|
62
|
-
type: 'technical',
|
|
63
|
-
abbreviation: 'BC',
|
|
64
|
-
},
|
|
65
|
-
mobile: {
|
|
66
|
-
name: 'Mobile development',
|
|
67
|
-
description: 'Mobile development',
|
|
68
|
-
type: 'technical',
|
|
69
|
-
},
|
|
70
|
-
tcp: {
|
|
71
|
-
name: 'TCP/IP',
|
|
72
|
-
description: 'TCP/IP',
|
|
73
|
-
type: 'technical',
|
|
74
|
-
},
|
|
75
|
-
cybersecurity: {
|
|
76
|
-
name: 'Cybersecurity',
|
|
77
|
-
description: 'Cybersecurity',
|
|
78
|
-
type: 'technical',
|
|
79
|
-
abbreviation: 'cyber',
|
|
80
|
-
},
|
|
81
|
-
ux: {
|
|
82
|
-
name: 'UX/UI',
|
|
83
|
-
description: 'User experience design, user interface design',
|
|
84
|
-
type: 'technical',
|
|
85
|
-
},
|
|
86
|
-
cloud: {
|
|
87
|
-
name: 'Cloud',
|
|
88
|
-
description: 'Cloud infra, deployment and scaling',
|
|
89
|
-
type: 'technical',
|
|
90
|
-
},
|
|
91
|
-
automation: {
|
|
92
|
-
name: 'Automation',
|
|
93
|
-
description:
|
|
94
|
-
'Automate tasks to reduce repetitive tasks and minimize potential errors',
|
|
95
|
-
type: 'technical',
|
|
96
|
-
abbreviation: 'autom.',
|
|
97
|
-
},
|
|
98
|
-
ci: {
|
|
99
|
-
name: 'CI/CD',
|
|
100
|
-
description:
|
|
101
|
-
'Set up CI/CD pipelines to maintain a consistent software release process',
|
|
102
|
-
type: 'technical',
|
|
103
|
-
},
|
|
104
|
-
testing: {
|
|
105
|
-
name: 'Testing',
|
|
106
|
-
description: 'TDD and other software testing strategies',
|
|
107
|
-
type: 'technical',
|
|
108
|
-
abbreviation: 'tests',
|
|
109
|
-
},
|
|
110
|
-
'curriculum-objectives-completed': {
|
|
111
|
-
name: 'Curriculum objectives completed',
|
|
112
|
-
description:
|
|
113
|
-
'Curriculum objectives completed to unlock the specialization branches',
|
|
114
|
-
type: 'technical',
|
|
115
|
-
abbreviation: 'credits',
|
|
116
|
-
},
|
|
117
|
-
|
|
118
|
-
// personal skills
|
|
119
|
-
// comm: {
|
|
120
|
-
// name: 'Communication',
|
|
121
|
-
// description: 'Communication, presentation, oral skills',
|
|
122
|
-
// type: 'personal',
|
|
123
|
-
// },
|
|
124
|
-
// team: {
|
|
125
|
-
// name: 'Team spirit',
|
|
126
|
-
// description: 'Ability to work with people',
|
|
127
|
-
// type: 'personal',
|
|
128
|
-
// },
|
|
129
|
-
// lead: {
|
|
130
|
-
// name: 'Leadership',
|
|
131
|
-
// description: 'Lead-taking, decision making',
|
|
132
|
-
// type: 'personal',
|
|
133
|
-
// },
|
|
134
|
-
// pro: {
|
|
135
|
-
// name: 'Professionalism',
|
|
136
|
-
// description: 'Responsible, reliable, on time',
|
|
137
|
-
// type: 'personal',
|
|
138
|
-
// },
|
|
139
|
-
// orga: {
|
|
140
|
-
// name: 'Organisation',
|
|
141
|
-
// description: 'Planning, time management',
|
|
142
|
-
// type: 'personal',
|
|
143
|
-
// },
|
|
144
|
-
// implication: {
|
|
145
|
-
// name: 'Implication',
|
|
146
|
-
// description: 'Motivated, involved in projects',
|
|
147
|
-
// type: 'personal',
|
|
148
|
-
// },
|
|
149
|
-
// initiative: {
|
|
150
|
-
// name: 'Self initiative',
|
|
151
|
-
// description: 'Autonomous, proactive',
|
|
152
|
-
// type: 'personal',
|
|
153
|
-
// },
|
|
154
|
-
// crea: {
|
|
155
|
-
// name: 'Creativity',
|
|
156
|
-
// description: 'Curiousity, inquisitiveness',
|
|
157
|
-
// type: 'personal',
|
|
158
|
-
// },
|
|
159
|
-
// precision: {
|
|
160
|
-
// name: 'Precision',
|
|
161
|
-
// description: 'Detail-oriented, clear code-writing',
|
|
162
|
-
// type: 'personal',
|
|
163
|
-
// },
|
|
164
|
-
|
|
165
|
-
// technologies
|
|
166
|
-
go: {
|
|
167
|
-
name: 'Go',
|
|
168
|
-
type: 'technology',
|
|
169
|
-
},
|
|
170
|
-
js: {
|
|
171
|
-
name: 'JS',
|
|
172
|
-
type: 'technology',
|
|
173
|
-
},
|
|
174
|
-
rust: {
|
|
175
|
-
name: 'Rust',
|
|
176
|
-
type: 'technology',
|
|
177
|
-
},
|
|
178
|
-
java: {
|
|
179
|
-
name: 'Java',
|
|
180
|
-
type: 'technology',
|
|
181
|
-
},
|
|
182
|
-
html: {
|
|
183
|
-
name: 'HTML',
|
|
184
|
-
type: 'technology',
|
|
185
|
-
},
|
|
186
|
-
css: {
|
|
187
|
-
name: 'CSS',
|
|
188
|
-
type: 'technology',
|
|
189
|
-
},
|
|
190
|
-
unix: {
|
|
191
|
-
name: 'Unix',
|
|
192
|
-
type: 'technology',
|
|
193
|
-
},
|
|
194
|
-
docker: {
|
|
195
|
-
name: 'Docker',
|
|
196
|
-
type: 'technology',
|
|
197
|
-
},
|
|
198
|
-
sql: {
|
|
199
|
-
name: 'SQL',
|
|
200
|
-
type: 'technology',
|
|
201
|
-
},
|
|
202
|
-
'no-sql': {
|
|
203
|
-
name: 'Non-relational Databases',
|
|
204
|
-
type: 'technology',
|
|
205
|
-
},
|
|
206
|
-
c: {
|
|
207
|
-
name: 'C',
|
|
208
|
-
type: 'technology',
|
|
209
|
-
},
|
|
210
|
-
sh: {
|
|
211
|
-
name: 'Shell',
|
|
212
|
-
type: 'technology',
|
|
213
|
-
},
|
|
214
|
-
php: {
|
|
215
|
-
name: 'PHP',
|
|
216
|
-
type: 'technology',
|
|
217
|
-
},
|
|
218
|
-
python: {
|
|
219
|
-
name: 'Python',
|
|
220
|
-
type: 'technology',
|
|
221
|
-
},
|
|
222
|
-
ruby: {
|
|
223
|
-
name: 'Ruby',
|
|
224
|
-
type: 'technology',
|
|
225
|
-
},
|
|
226
|
-
'c-sharp': {
|
|
227
|
-
name: 'C#',
|
|
228
|
-
type: 'technology',
|
|
229
|
-
abbreviation: 'C#',
|
|
230
|
-
},
|
|
231
|
-
'c-pp': {
|
|
232
|
-
name: 'C++',
|
|
233
|
-
type: 'technology',
|
|
234
|
-
abbreviation: 'C++',
|
|
235
|
-
},
|
|
236
|
-
graphql: {
|
|
237
|
-
name: 'GraphQL',
|
|
238
|
-
type: 'technology',
|
|
239
|
-
abbreviation: 'GQL',
|
|
240
|
-
},
|
|
241
|
-
rails: {
|
|
242
|
-
name: 'Ruby on Rails',
|
|
243
|
-
type: 'technology',
|
|
244
|
-
},
|
|
245
|
-
laravel: {
|
|
246
|
-
name: 'Laravel',
|
|
247
|
-
type: 'technology',
|
|
248
|
-
},
|
|
249
|
-
django: {
|
|
250
|
-
name: 'Django',
|
|
251
|
-
type: 'technology',
|
|
252
|
-
},
|
|
253
|
-
react: {
|
|
254
|
-
name: 'React',
|
|
255
|
-
type: 'technology',
|
|
256
|
-
},
|
|
257
|
-
dotnet: {
|
|
258
|
-
name: '.NET',
|
|
259
|
-
type: 'technology',
|
|
260
|
-
},
|
|
261
|
-
electron: {
|
|
262
|
-
name: 'Electron',
|
|
263
|
-
type: 'technology',
|
|
264
|
-
abbreviation: 'elect.',
|
|
265
|
-
},
|
|
266
|
-
git: {
|
|
267
|
-
name: 'Git',
|
|
268
|
-
type: 'technology',
|
|
269
|
-
},
|
|
270
|
-
employability: {
|
|
271
|
-
name: 'Employability',
|
|
272
|
-
type: 'employability',
|
|
273
|
-
abbreviation: 'jobSkills',
|
|
274
|
-
},
|
|
275
|
-
'personal-development': {
|
|
276
|
-
name: 'Personal Development',
|
|
277
|
-
description:
|
|
278
|
-
'Focuses on self-awareness, self-management, communication, and core values to build a strong personal foundation for growth and autonomy.',
|
|
279
|
-
type: 'lifeskills',
|
|
280
|
-
abbreviation: 'PDev',
|
|
281
|
-
},
|
|
282
|
-
'relational-development': {
|
|
283
|
-
name: 'Relational Development',
|
|
284
|
-
description:
|
|
285
|
-
'Develops the ability to connect with others through assertiveness, empathy, and resilience, enabling healthy collaboration and conflict management.',
|
|
286
|
-
type: 'lifeskills',
|
|
287
|
-
abbreviation: 'RelDev',
|
|
288
|
-
},
|
|
289
|
-
'professional-development': {
|
|
290
|
-
name: 'Professional Development',
|
|
291
|
-
description:
|
|
292
|
-
'Strengthens strategic thinking, leadership, and professional presence to drive impact, solve complex problems, and succeed in professional environments.',
|
|
293
|
-
type: 'lifeskills',
|
|
294
|
-
abbreviation: 'ProDev',
|
|
295
|
-
},
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
export const skillTiers = [
|
|
299
|
-
{ tier: 'Beginner', name: 'Code Explorer', maxValue: 25 },
|
|
300
|
-
{ tier: 'Intermediate', name: 'Bug Squasher', maxValue: 50 },
|
|
301
|
-
{ tier: 'Advanced', name: 'Script Wizard', maxValue: 75 },
|
|
302
|
-
{ tier: 'Master', name: 'Master Hacker', maxValue: 100 },
|
|
303
|
-
]
|
|
304
|
-
export const skillTypes = [
|
|
305
|
-
{
|
|
306
|
-
type: 'technical',
|
|
307
|
-
name: 'Technical skills',
|
|
308
|
-
description:
|
|
309
|
-
'Technical skills are based on notions that are taught during the curriculum ; they represent what you learned from a project. They can be acquired when completing piscines, projects & exams.',
|
|
310
|
-
},
|
|
311
|
-
// {
|
|
312
|
-
// type: 'personal',
|
|
313
|
-
// name: 'Personal skills',
|
|
314
|
-
// description:
|
|
315
|
-
// 'Personal skills are based on feedback given by classmates that worked with you about your personal qualities & abilities ; they represent what people observed about you.',
|
|
316
|
-
// },
|
|
317
|
-
{
|
|
318
|
-
type: 'technology',
|
|
319
|
-
name: 'Technologies',
|
|
320
|
-
description:
|
|
321
|
-
'Technologies gather the different programming languages, frameworks and platforms acquired from projects & piscines.',
|
|
322
|
-
},
|
|
323
|
-
{
|
|
324
|
-
type: 'employability',
|
|
325
|
-
name: 'Employability',
|
|
326
|
-
description:
|
|
327
|
-
'Develops professional readiness through personal branding, digital presence, and job search strategies—including portfolio building, CV writing, and effective networking.',
|
|
328
|
-
},
|
|
329
|
-
{
|
|
330
|
-
type: 'lifeskills',
|
|
331
|
-
name: 'Life Skills',
|
|
332
|
-
description:
|
|
333
|
-
'Builds essential personal, relational, and professional competencies through structured learning and practical activities, strengthening communication, collaboration, resilience, and leadership.',
|
|
334
|
-
},
|
|
335
|
-
]
|
|
336
|
-
|
|
337
|
-
export const hasRequiredSkills = (requiredSkills, userSkills) =>
|
|
338
|
-
Object.entries(requiredSkills || {}).every(
|
|
339
|
-
([skillName, requiredAmount]) =>
|
|
340
|
-
(userSkills?.[skillName] || 0) >= requiredAmount,
|
|
341
|
-
)
|
|
342
|
-
|
|
343
|
-
export const extractHighestSkills = (node, result = {}) => {
|
|
344
|
-
if (node?.attrs?.baseSkills) {
|
|
345
|
-
for (const [skill, value] of Object.entries(node.attrs.baseSkills)) {
|
|
346
|
-
if (!result[skill] || value > result[skill]) {
|
|
347
|
-
result[skill] = value
|
|
348
|
-
}
|
|
349
|
-
}
|
|
350
|
-
}
|
|
351
|
-
|
|
352
|
-
if (node.children) {
|
|
353
|
-
for (const child of Object.values(node.children)) {
|
|
354
|
-
extractHighestSkills(child, result) // recursively get skills rewarded by children (in the case of piscines>exercises)
|
|
355
|
-
}
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
return result
|
|
359
|
-
}
|