@vue-skuilder/courseware 0.1.8-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.
- package/dist/CourseWare.d.ts +18 -0
- package/dist/CourseWare.d.ts.map +1 -0
- package/dist/assets/index.css +1 -0
- package/dist/chess/chessUtils.d.ts +17 -0
- package/dist/chess/chessUtils.d.ts.map +1 -0
- package/dist/chess/chessground/anim.d.ts +18 -0
- package/dist/chess/chessground/anim.d.ts.map +1 -0
- package/dist/chess/chessground/api.d.ts +29 -0
- package/dist/chess/chessground/api.d.ts.map +1 -0
- package/dist/chess/chessground/autoPieces.d.ts +4 -0
- package/dist/chess/chessground/autoPieces.d.ts.map +1 -0
- package/dist/chess/chessground/board.d.ts +26 -0
- package/dist/chess/chessground/board.d.ts.map +1 -0
- package/dist/chess/chessground/chessground.d.ts +8 -0
- package/dist/chess/chessground/chessground.d.ts.map +1 -0
- package/dist/chess/chessground/config.d.ts +88 -0
- package/dist/chess/chessground/config.d.ts.map +1 -0
- package/dist/chess/chessground/drag.d.ts +21 -0
- package/dist/chess/chessground/drag.d.ts.map +1 -0
- package/dist/chess/chessground/draw.d.ts +66 -0
- package/dist/chess/chessground/draw.d.ts.map +1 -0
- package/dist/chess/chessground/drop.d.ts +6 -0
- package/dist/chess/chessground/drop.d.ts.map +1 -0
- package/dist/chess/chessground/events.d.ts +5 -0
- package/dist/chess/chessground/events.d.ts.map +1 -0
- package/dist/chess/chessground/explosion.d.ts +4 -0
- package/dist/chess/chessground/explosion.d.ts.map +1 -0
- package/dist/chess/chessground/fen.d.ts +5 -0
- package/dist/chess/chessground/fen.d.ts.map +1 -0
- package/dist/chess/chessground/premove.d.ts +7 -0
- package/dist/chess/chessground/premove.d.ts.map +1 -0
- package/dist/chess/chessground/render.d.ts +5 -0
- package/dist/chess/chessground/render.d.ts.map +1 -0
- package/dist/chess/chessground/state.d.ts +101 -0
- package/dist/chess/chessground/state.d.ts.map +1 -0
- package/dist/chess/chessground/svg.d.ts +9 -0
- package/dist/chess/chessground/svg.d.ts.map +1 -0
- package/dist/chess/chessground/sync.d.ts +9 -0
- package/dist/chess/chessground/sync.d.ts.map +1 -0
- package/dist/chess/chessground/types.d.ts +94 -0
- package/dist/chess/chessground/types.d.ts.map +1 -0
- package/dist/chess/chessground/util.d.ts +21 -0
- package/dist/chess/chessground/util.d.ts.map +1 -0
- package/dist/chess/chessground/wrap.d.ts +4 -0
- package/dist/chess/chessground/wrap.d.ts.map +1 -0
- package/dist/chess/components/ChessBoard.vue.d.ts +48 -0
- package/dist/chess/components/ChessBoard.vue.d.ts.map +1 -0
- package/dist/chess/components/types.d.ts +11 -0
- package/dist/chess/components/types.d.ts.map +1 -0
- package/dist/chess/composables/useChessEngine.d.ts +303 -0
- package/dist/chess/composables/useChessEngine.d.ts.map +1 -0
- package/dist/chess/composables/usePromotionDialog.d.ts +38 -0
- package/dist/chess/composables/usePromotionDialog.d.ts.map +1 -0
- package/dist/chess/index.d.ts +4 -0
- package/dist/chess/index.d.ts.map +1 -0
- package/dist/chess/questions/forks/forksView.vue.d.ts +52 -0
- package/dist/chess/questions/forks/forksView.vue.d.ts.map +1 -0
- package/dist/chess/questions/forks/index.d.ts +86 -0
- package/dist/chess/questions/forks/index.d.ts.map +1 -0
- package/dist/chess/questions/puzzle/index.d.ts +25 -0
- package/dist/chess/questions/puzzle/index.d.ts.map +1 -0
- package/dist/chess/questions/puzzle/puzzle.vue.d.ts +55 -0
- package/dist/chess/questions/puzzle/puzzle.vue.d.ts.map +1 -0
- package/dist/components/MusicScoreRender.vue.d.ts +13 -0
- package/dist/components/MusicScoreRender.vue.d.ts.map +1 -0
- package/dist/default/index.d.ts +4 -0
- package/dist/default/index.d.ts.map +1 -0
- package/dist/default/questions/fillIn/blanksCorrection.d.ts +3 -0
- package/dist/default/questions/fillIn/blanksCorrection.d.ts.map +1 -0
- package/dist/default/questions/fillIn/fillIn.vue.d.ts +41 -0
- package/dist/default/questions/fillIn/fillIn.vue.d.ts.map +1 -0
- package/dist/default/questions/fillIn/index.d.ts +105 -0
- package/dist/default/questions/fillIn/index.d.ts.map +1 -0
- package/dist/french/index.d.ts +4 -0
- package/dist/french/index.d.ts.map +1 -0
- package/dist/french/questions/audioparse/index.d.ts +65 -0
- package/dist/french/questions/audioparse/index.d.ts.map +1 -0
- package/dist/french/questions/audioparse/view.vue.d.ts +31 -0
- package/dist/french/questions/audioparse/view.vue.d.ts.map +1 -0
- package/dist/french/questions/vocab/identify.vue.d.ts +27 -0
- package/dist/french/questions/vocab/identify.vue.d.ts.map +1 -0
- package/dist/french/questions/vocab/index.d.ts +54 -0
- package/dist/french/questions/vocab/index.d.ts.map +1 -0
- package/dist/index.cjs.js +75 -0
- package/dist/index.cjs.js.map +1 -0
- package/dist/index.d.ts +86 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.mjs +63128 -0
- package/dist/index.mjs.map +1 -0
- package/dist/math/index.d.ts +4 -0
- package/dist/math/index.d.ts.map +1 -0
- package/dist/math/questions/addition/horizontal.vue.d.ts +46 -0
- package/dist/math/questions/addition/horizontal.vue.d.ts.map +1 -0
- package/dist/math/questions/addition/index.d.ts +24 -0
- package/dist/math/questions/addition/index.d.ts.map +1 -0
- package/dist/math/questions/addition/verbal.vue.d.ts +46 -0
- package/dist/math/questions/addition/verbal.vue.d.ts.map +1 -0
- package/dist/math/questions/angleCategorize/angleCategorize.vue.d.ts +30 -0
- package/dist/math/questions/angleCategorize/angleCategorize.vue.d.ts.map +1 -0
- package/dist/math/questions/angleCategorize/index.d.ts +76 -0
- package/dist/math/questions/angleCategorize/index.d.ts.map +1 -0
- package/dist/math/questions/countBy/default.vue.d.ts +29 -0
- package/dist/math/questions/countBy/default.vue.d.ts.map +1 -0
- package/dist/math/questions/countBy/index.d.ts +81 -0
- package/dist/math/questions/countBy/index.d.ts.map +1 -0
- package/dist/math/questions/division/horizontal.vue.d.ts +31 -0
- package/dist/math/questions/division/horizontal.vue.d.ts.map +1 -0
- package/dist/math/questions/division/index.d.ts +75 -0
- package/dist/math/questions/division/index.d.ts.map +1 -0
- package/dist/math/questions/equalityTest/index.d.ts +77 -0
- package/dist/math/questions/equalityTest/index.d.ts.map +1 -0
- package/dist/math/questions/equalityTest/trueFalse.vue.d.ts +33 -0
- package/dist/math/questions/equalityTest/trueFalse.vue.d.ts.map +1 -0
- package/dist/math/questions/multiplication/blorizontal.vue.d.ts +31 -0
- package/dist/math/questions/multiplication/blorizontal.vue.d.ts.map +1 -0
- package/dist/math/questions/multiplication/index.d.ts +71 -0
- package/dist/math/questions/multiplication/index.d.ts.map +1 -0
- package/dist/math/questions/multiplication/verbal.vue.d.ts +31 -0
- package/dist/math/questions/multiplication/verbal.vue.d.ts.map +1 -0
- package/dist/math/questions/oneStepEqn/index.d.ts +82 -0
- package/dist/math/questions/oneStepEqn/index.d.ts.map +1 -0
- package/dist/math/questions/oneStepEqn/solve.vue.d.ts +32 -0
- package/dist/math/questions/oneStepEqn/solve.vue.d.ts.map +1 -0
- package/dist/math/questions/supplementaryAngles/index.d.ts +72 -0
- package/dist/math/questions/supplementaryAngles/index.d.ts.map +1 -0
- package/dist/math/questions/supplementaryAngles/supplementaryAngles.vue.d.ts +31 -0
- package/dist/math/questions/supplementaryAngles/supplementaryAngles.vue.d.ts.map +1 -0
- package/dist/math/utility/Fraction.d.ts +18 -0
- package/dist/math/utility/Fraction.d.ts.map +1 -0
- package/dist/math/utility/index.d.ts +19 -0
- package/dist/math/utility/index.d.ts.map +1 -0
- package/dist/piano/NoteDisplay.vue.d.ts +25 -0
- package/dist/piano/NoteDisplay.vue.d.ts.map +1 -0
- package/dist/piano/index.d.ts +4 -0
- package/dist/piano/index.d.ts.map +1 -0
- package/dist/piano/questions/echo/Playback.vue.d.ts +369 -0
- package/dist/piano/questions/echo/Playback.vue.d.ts.map +1 -0
- package/dist/piano/questions/echo/index.d.ts +744 -0
- package/dist/piano/questions/echo/index.d.ts.map +1 -0
- package/dist/piano/questions/playNote/NotePlayback.vue.d.ts +208 -0
- package/dist/piano/questions/playNote/NotePlayback.vue.d.ts.map +1 -0
- package/dist/piano/questions/playNote/index.d.ts +419 -0
- package/dist/piano/questions/playNote/index.d.ts.map +1 -0
- package/dist/piano/utility/MidiConfig.vue.d.ts +113 -0
- package/dist/piano/utility/MidiConfig.vue.d.ts.map +1 -0
- package/dist/piano/utility/PianoRangeVisualizer.vue.d.ts +41 -0
- package/dist/piano/utility/PianoRangeVisualizer.vue.d.ts.map +1 -0
- package/dist/piano/utility/SyllableSeqVis.vue.d.ts +36 -0
- package/dist/piano/utility/SyllableSeqVis.vue.d.ts.map +1 -0
- package/dist/piano/utility/midi.d.ts +82 -0
- package/dist/piano/utility/midi.d.ts.map +1 -0
- package/dist/pitch/index.d.ts +4 -0
- package/dist/pitch/index.d.ts.map +1 -0
- package/dist/pitch/questions/indentify/index.d.ts +76 -0
- package/dist/pitch/questions/indentify/index.d.ts.map +1 -0
- package/dist/pitch/questions/indentify/textBox.vue.d.ts +31 -0
- package/dist/pitch/questions/indentify/textBox.vue.d.ts.map +1 -0
- package/dist/sightsing/index.d.ts +4 -0
- package/dist/sightsing/index.d.ts.map +1 -0
- package/dist/sightsing/questions/IdentifyKey/IdentifyKey.vue.d.ts +43 -0
- package/dist/sightsing/questions/IdentifyKey/IdentifyKey.vue.d.ts.map +1 -0
- package/dist/sightsing/questions/IdentifyKey/index.d.ts +117 -0
- package/dist/sightsing/questions/IdentifyKey/index.d.ts.map +1 -0
- package/dist/typing/index.d.ts +4 -0
- package/dist/typing/index.d.ts.map +1 -0
- package/dist/typing/questions/falling-letters/FallingLetters.vue.d.ts +62 -0
- package/dist/typing/questions/falling-letters/FallingLetters.vue.d.ts.map +1 -0
- package/dist/typing/questions/falling-letters/index.d.ts +144 -0
- package/dist/typing/questions/falling-letters/index.d.ts.map +1 -0
- package/dist/typing/questions/falling-letters/types.d.ts +13 -0
- package/dist/typing/questions/falling-letters/types.d.ts.map +1 -0
- package/dist/typing/questions/single-letter/index.d.ts +67 -0
- package/dist/typing/questions/single-letter/index.d.ts.map +1 -0
- package/dist/typing/questions/single-letter/typeSingleLetter.vue.d.ts +28 -0
- package/dist/typing/questions/single-letter/typeSingleLetter.vue.d.ts.map +1 -0
- package/dist/word-work/ankiCardGen/data.d.ts +63 -0
- package/dist/word-work/ankiCardGen/data.d.ts.map +1 -0
- package/dist/word-work/index.d.ts +4 -0
- package/dist/word-work/index.d.ts.map +1 -0
- package/dist/word-work/questions/spelling/index.d.ts +69 -0
- package/dist/word-work/questions/spelling/index.d.ts.map +1 -0
- package/dist/word-work/questions/spelling/textBox.vue.d.ts +32 -0
- package/dist/word-work/questions/spelling/textBox.vue.d.ts.map +1 -0
- package/package.json +60 -0
- package/src/logic.d.ts +26 -0
- package/src/logic.js +202 -0
package/src/logic.js
ADDED
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
// Node.js compatible business logic extracted from vue-skuilder/courses
|
|
2
|
+
// Contains essential fill-in-blank question parsing and grading logic
|
|
3
|
+
|
|
4
|
+
// ===== UTILITY FUNCTIONS =====
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
// [ ] Todo: deduplicate this code.
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
* Utility to split text by left and right delimiters (e.g., {{ and }})
|
|
11
|
+
* Extracted from packages/common-ui/src/components/cardRendering/MarkdownRendererHelpers.ts
|
|
12
|
+
*/
|
|
13
|
+
function splitByDelimiters(text, leftDelim, rightDelim) {
|
|
14
|
+
const result = [];
|
|
15
|
+
|
|
16
|
+
let remaining = text;
|
|
17
|
+
|
|
18
|
+
while (remaining.includes(leftDelim)) {
|
|
19
|
+
const leftIndex = remaining.indexOf(leftDelim);
|
|
20
|
+
const rightIndex = remaining.indexOf(rightDelim, leftIndex + leftDelim.length);
|
|
21
|
+
|
|
22
|
+
if (rightIndex === -1) {
|
|
23
|
+
// No closing delimiter found, treat rest as plain text
|
|
24
|
+
if (remaining.length > 0) {
|
|
25
|
+
result.push({ beforeMatch: remaining, match: '', afterMatch: '' });
|
|
26
|
+
}
|
|
27
|
+
break;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const beforeMatch = remaining.substring(0, leftIndex);
|
|
31
|
+
const match = remaining.substring(leftIndex, rightIndex + rightDelim.length);
|
|
32
|
+
const afterMatch = remaining.substring(rightIndex + rightDelim.length);
|
|
33
|
+
|
|
34
|
+
result.push({ beforeMatch, match, afterMatch });
|
|
35
|
+
remaining = afterMatch;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Add any remaining text
|
|
39
|
+
if (remaining.length > 0 && !result.some((r) => r.afterMatch === remaining)) {
|
|
40
|
+
result.push({ beforeMatch: remaining, match: '', afterMatch: '' });
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return result;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Simple random integer generator
|
|
48
|
+
*/
|
|
49
|
+
function randomInt(min, max) {
|
|
50
|
+
return Math.floor(Math.random() * (max - min + 1)) + min;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Simple array shuffle (Lodash-style)
|
|
55
|
+
*/
|
|
56
|
+
function shuffle(array) {
|
|
57
|
+
const result = [...array];
|
|
58
|
+
for (let i = result.length - 1; i > 0; i--) {
|
|
59
|
+
const j = Math.floor(Math.random() * (i + 1));
|
|
60
|
+
[result[i], result[j]] = [result[j], result[i]];
|
|
61
|
+
}
|
|
62
|
+
return result;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// ===== CORE PARSING LOGIC =====
|
|
66
|
+
|
|
67
|
+
// TypeScript interfaces converted to JSDoc comments for reference:
|
|
68
|
+
// ParsedBlank: { answers: string[], options: string[] | null }
|
|
69
|
+
// ViewData: { [key: string]: any, content?: string }
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Parse options from {{answer}} or {{answer1|answer2||distractor1|distractor2}} syntax
|
|
73
|
+
* Extracted from BlanksCard.optionsFromString() method
|
|
74
|
+
*/
|
|
75
|
+
function optionsFromString(s) {
|
|
76
|
+
if (!s.startsWith('{{') || !s.endsWith('}}')) {
|
|
77
|
+
throw new Error(`string ${s} is not fill-in text - must look like "{{someText}}"`);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
s = s.substring(2, s.length - 2);
|
|
81
|
+
const split = s.split('||');
|
|
82
|
+
|
|
83
|
+
if (split.length > 1) {
|
|
84
|
+
// Multiple choice format: {{answer1|answer2||distractor1|distractor2}}
|
|
85
|
+
const answers = split[0].split('|').map((a) => a.trim());
|
|
86
|
+
|
|
87
|
+
// Remove answers from distractors (makes for easier editing)
|
|
88
|
+
const distractors = split[1]
|
|
89
|
+
.split('|')
|
|
90
|
+
.map((d) => d.trim())
|
|
91
|
+
.filter((d) => !answers.includes(d));
|
|
92
|
+
|
|
93
|
+
const options = [...distractors];
|
|
94
|
+
options.push(answers[randomInt(0, answers.length - 1)]);
|
|
95
|
+
|
|
96
|
+
return {
|
|
97
|
+
answers,
|
|
98
|
+
options: shuffle(options),
|
|
99
|
+
};
|
|
100
|
+
} else {
|
|
101
|
+
// Fill-in-blank format: {{answer}}
|
|
102
|
+
return {
|
|
103
|
+
answers: [s.trim()],
|
|
104
|
+
options: null,
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// ===== BLANKS CARD CLASS =====
|
|
110
|
+
|
|
111
|
+
export class BlanksCard {
|
|
112
|
+
constructor(data) {
|
|
113
|
+
if (!data || data.length === 0) {
|
|
114
|
+
throw new Error('BlanksCard requires ViewData');
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
const content = String(data[0]?.content || '');
|
|
118
|
+
|
|
119
|
+
// Find all {{...}} patterns
|
|
120
|
+
const splitText = splitByDelimiters(content, '{{', '}}');
|
|
121
|
+
let processedText = content;
|
|
122
|
+
|
|
123
|
+
// Process the first blank found (simplified from original)
|
|
124
|
+
for (const segment of splitText) {
|
|
125
|
+
if (segment.match && segment.match.startsWith('{{') && segment.match.endsWith('}}')) {
|
|
126
|
+
const parsed = optionsFromString(segment.match);
|
|
127
|
+
this.answers = parsed.answers;
|
|
128
|
+
this.options = parsed.options;
|
|
129
|
+
|
|
130
|
+
// Replace the blank with a placeholder for display
|
|
131
|
+
const placeholder = this.options ? '[Multiple Choice]' : '[Fill in the blank]';
|
|
132
|
+
processedText = processedText.replace(segment.match, placeholder);
|
|
133
|
+
break; // Only process first blank for MVP
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
this.mdText = processedText;
|
|
138
|
+
|
|
139
|
+
// Fallback if no blanks found
|
|
140
|
+
if (!this.answers) {
|
|
141
|
+
this.answers = [];
|
|
142
|
+
this.options = null;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Check if a given answer is correct
|
|
148
|
+
*/
|
|
149
|
+
isCorrect(answer) {
|
|
150
|
+
if (typeof answer === 'string') {
|
|
151
|
+
return this.answers.includes(answer.trim());
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
if (Array.isArray(answer)) {
|
|
155
|
+
return answer.every((a, index) => index < this.answers.length && this.answers[index] === a);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// Multiple choice format: {choiceList: string[], selection: number}
|
|
159
|
+
if (answer && typeof answer === 'object' && 'selection' in answer && 'choiceList' in answer) {
|
|
160
|
+
const selectedChoice = answer.choiceList[answer.selection];
|
|
161
|
+
return this.answers.includes(selectedChoice);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
return false;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// ===== SPELLING GRADING =====
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Grade a spelling attempt and provide visual feedback
|
|
172
|
+
* Extracted from packages/courseware/src/default/questions/fillIn/blanksCorrection.ts
|
|
173
|
+
*/
|
|
174
|
+
export function gradeSpellingAttempt(attempt, answer) {
|
|
175
|
+
const result = new Array(answer.length).fill('_');
|
|
176
|
+
const attemptChars = attempt.split('');
|
|
177
|
+
|
|
178
|
+
// First pass: match characters in correct positions
|
|
179
|
+
for (let i = 0; i < answer.length; i++) {
|
|
180
|
+
if (i < attemptChars.length && attemptChars[i] === answer[i]) {
|
|
181
|
+
result[i] = attemptChars[i];
|
|
182
|
+
attemptChars[i] = '';
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// Second pass: match remaining characters from right to left
|
|
187
|
+
for (let i = answer.length - 1; i >= 0; i--) {
|
|
188
|
+
if (result[i] === '_') {
|
|
189
|
+
const charIndex = attemptChars.findIndex((char) => char === answer[i]);
|
|
190
|
+
if (charIndex !== -1) {
|
|
191
|
+
result[i] = answer[i];
|
|
192
|
+
attemptChars[charIndex] = '';
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
return result.join(' ');
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// ===== EXPORTS =====
|
|
201
|
+
|
|
202
|
+
export { optionsFromString, splitByDelimiters };
|