@ooneex/gamification 0.0.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/LICENSE +21 -0
- package/README.md +1 -0
- package/dist/flashcard/index.d.ts +683 -0
- package/dist/flashcard/index.js +3 -0
- package/dist/flashcard/index.js.map +11 -0
- package/dist/index.d.ts +40 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +11 -0
- package/dist/mcq/index.d.ts +98 -0
- package/dist/mcq/index.js +3 -0
- package/dist/mcq/index.js.map +10 -0
- package/package.json +51 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Ooneex
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# @ooneex/gamification
|
|
@@ -0,0 +1,683 @@
|
|
|
1
|
+
import { IImage } from "@ooneex/image";
|
|
2
|
+
import { IStatus } from "@ooneex/status";
|
|
3
|
+
import { ITag } from "@ooneex/tag";
|
|
4
|
+
import { IBase as IBase2, IStat } from "@ooneex/types";
|
|
5
|
+
import { IBase } from "@ooneex/types";
|
|
6
|
+
interface ILevel extends IBase {
|
|
7
|
+
name: string;
|
|
8
|
+
code: string;
|
|
9
|
+
color: string;
|
|
10
|
+
}
|
|
11
|
+
declare enum ESessionType {
|
|
12
|
+
/** Learning-focused session with detailed explanations and guided experience */
|
|
13
|
+
TRAINING = "training",
|
|
14
|
+
/** Reinforcement session for solidifying already learned knowledge */
|
|
15
|
+
PRACTICE = "practice",
|
|
16
|
+
/** Mock test environment simulating real exam conditions */
|
|
17
|
+
SIMULATION = "simulation",
|
|
18
|
+
/** Quick knowledge check with immediate feedback */
|
|
19
|
+
QUIZ = "quiz",
|
|
20
|
+
/** Competitive or difficult questions designed to test limits */
|
|
21
|
+
CHALLENGE = "challenge",
|
|
22
|
+
/** Multiplayer competitive session with rankings and prizes */
|
|
23
|
+
TOURNAMENT = "tournament",
|
|
24
|
+
/** Session for revisiting previously answered questions and mistakes */
|
|
25
|
+
REVIEW = "review",
|
|
26
|
+
/** Initial assessment to identify knowledge gaps and skill levels */
|
|
27
|
+
DIAGNOSTIC = "diagnostic",
|
|
28
|
+
/** Time-pressured rapid-fire questions focusing on speed and accuracy */
|
|
29
|
+
SPEED_TEST = "speed_test"
|
|
30
|
+
}
|
|
31
|
+
declare enum EFlashcardState {
|
|
32
|
+
/** Brand new card that hasn't been studied yet */
|
|
33
|
+
NEW = "new",
|
|
34
|
+
/** Card in learning phase with short intervals */
|
|
35
|
+
LEARNING = "learning",
|
|
36
|
+
/** Card in relearning phase after being forgotten */
|
|
37
|
+
RELEARNING = "relearning",
|
|
38
|
+
/** Graduated card in long-term review cycle */
|
|
39
|
+
REVIEW = "review",
|
|
40
|
+
/** Card temporarily hidden until next day */
|
|
41
|
+
BURIED = "buried",
|
|
42
|
+
/** Card permanently hidden from reviews */
|
|
43
|
+
SUSPENDED = "suspended"
|
|
44
|
+
}
|
|
45
|
+
declare enum EFlashcardRating {
|
|
46
|
+
/** Incorrect answer - restart learning */
|
|
47
|
+
AGAIN = "again",
|
|
48
|
+
/** Correct but difficult - shorter interval */
|
|
49
|
+
HARD = "hard",
|
|
50
|
+
/** Correct with some effort - normal interval */
|
|
51
|
+
GOOD = "good",
|
|
52
|
+
/** Correct with no effort - longer interval */
|
|
53
|
+
EASY = "easy"
|
|
54
|
+
}
|
|
55
|
+
declare enum EFlashcardSessionStatus {
|
|
56
|
+
DRAFT = "draft",
|
|
57
|
+
STARTED = "started",
|
|
58
|
+
PAUSED = "paused",
|
|
59
|
+
COMPLETED = "completed"
|
|
60
|
+
}
|
|
61
|
+
declare enum EFlashcardAlgorithm {
|
|
62
|
+
/** Legacy SuperMemo 2 algorithm */
|
|
63
|
+
SM2 = "sm2",
|
|
64
|
+
/** Free Spaced Repetition Scheduler (modern) */
|
|
65
|
+
FSRS = "fsrs"
|
|
66
|
+
}
|
|
67
|
+
interface IFlashcardSchedule extends IBase2 {
|
|
68
|
+
/** Current state of the card */
|
|
69
|
+
state: EFlashcardState;
|
|
70
|
+
/** Days until next review */
|
|
71
|
+
interval: number;
|
|
72
|
+
/** Ease factor for SM-2 algorithm (2.5 = 250%) */
|
|
73
|
+
easeFactor: number;
|
|
74
|
+
/** Number of times card has been reviewed */
|
|
75
|
+
reviewCount: number;
|
|
76
|
+
/** Number of times card has failed (lapses) */
|
|
77
|
+
lapseCount: number;
|
|
78
|
+
/** Current step in learning/relearning sequence */
|
|
79
|
+
currentStep: number;
|
|
80
|
+
/** When the card is due for review */
|
|
81
|
+
dueDate: Date;
|
|
82
|
+
/** Last time the card was reviewed */
|
|
83
|
+
lastReviewedAt?: Date | null;
|
|
84
|
+
/** FSRS-specific parameters */
|
|
85
|
+
difficulty?: number;
|
|
86
|
+
stability?: number;
|
|
87
|
+
retrievability?: number;
|
|
88
|
+
/** Learning steps for this card (in minutes) */
|
|
89
|
+
learningSteps: number[];
|
|
90
|
+
/** Relearning steps for this card (in minutes) */
|
|
91
|
+
relearningSteps: number[];
|
|
92
|
+
}
|
|
93
|
+
interface IFlashcard extends IBase2 {
|
|
94
|
+
/** Front side content */
|
|
95
|
+
front: string;
|
|
96
|
+
/** Back side content */
|
|
97
|
+
back: string;
|
|
98
|
+
/** Optional hint text */
|
|
99
|
+
hint?: string;
|
|
100
|
+
/** Optional context or source */
|
|
101
|
+
context?: string;
|
|
102
|
+
contextId?: string;
|
|
103
|
+
/** Scheduling information */
|
|
104
|
+
schedule: IFlashcardSchedule;
|
|
105
|
+
/** Additional metadata */
|
|
106
|
+
tags?: ITag[];
|
|
107
|
+
stat?: IStat;
|
|
108
|
+
status?: IStatus;
|
|
109
|
+
image?: IImage;
|
|
110
|
+
}
|
|
111
|
+
interface IFlashcardReview extends IBase2 {
|
|
112
|
+
/** The flashcard being reviewed */
|
|
113
|
+
card: IFlashcard;
|
|
114
|
+
/** Session this review belongs to */
|
|
115
|
+
session: IFlashcardSession;
|
|
116
|
+
/** User's rating for this review */
|
|
117
|
+
rating: EFlashcardRating;
|
|
118
|
+
/** Time taken to answer (in seconds) */
|
|
119
|
+
responseTime: number;
|
|
120
|
+
/** Previous interval before this review */
|
|
121
|
+
previousInterval: number;
|
|
122
|
+
/** New interval after this review */
|
|
123
|
+
newInterval: number;
|
|
124
|
+
/** Previous ease factor */
|
|
125
|
+
previousEaseFactor: number;
|
|
126
|
+
/** New ease factor */
|
|
127
|
+
newEaseFactor: number;
|
|
128
|
+
/** Previous due date */
|
|
129
|
+
previousDueDate: Date;
|
|
130
|
+
/** New due date */
|
|
131
|
+
newDueDate: Date;
|
|
132
|
+
/** Previous card state */
|
|
133
|
+
previousState: EFlashcardState;
|
|
134
|
+
/** New card state */
|
|
135
|
+
newState: EFlashcardState;
|
|
136
|
+
/** Whether this was a lapse (forgotten card) */
|
|
137
|
+
wasLapse: boolean;
|
|
138
|
+
/** Algorithm used for scheduling */
|
|
139
|
+
algorithm: EFlashcardAlgorithm;
|
|
140
|
+
/** Review timestamp */
|
|
141
|
+
reviewedAt: Date;
|
|
142
|
+
}
|
|
143
|
+
interface IFlashcardSession extends IBase2 {
|
|
144
|
+
name: string;
|
|
145
|
+
/** Total cards available for study */
|
|
146
|
+
totalCards: number;
|
|
147
|
+
/** Number of new cards in session */
|
|
148
|
+
newCardsCount: number;
|
|
149
|
+
/** Number of learning cards in session */
|
|
150
|
+
learningCardsCount: number;
|
|
151
|
+
/** Number of review cards in session */
|
|
152
|
+
reviewCardsCount: number;
|
|
153
|
+
/** Cards studied so far */
|
|
154
|
+
studiedCount: number;
|
|
155
|
+
/** Cards answered correctly */
|
|
156
|
+
correctCount: number;
|
|
157
|
+
/** Cards answered incorrectly */
|
|
158
|
+
incorrectCount: number;
|
|
159
|
+
/** Total study time in seconds */
|
|
160
|
+
studyTime: number;
|
|
161
|
+
/** Cards in this session */
|
|
162
|
+
cards: IFlashcard[];
|
|
163
|
+
/** Reviews completed in this session */
|
|
164
|
+
reviews: IFlashcardReview[];
|
|
165
|
+
/** Session status */
|
|
166
|
+
status: EFlashcardSessionStatus;
|
|
167
|
+
/** Overall session score (0-100) */
|
|
168
|
+
score: number;
|
|
169
|
+
/** Session start time */
|
|
170
|
+
startedAt?: Date | null;
|
|
171
|
+
/** Session pause time */
|
|
172
|
+
pausedAt?: Date | null;
|
|
173
|
+
/** Session resume time */
|
|
174
|
+
resumedAt?: Date | null;
|
|
175
|
+
/** Session completion time */
|
|
176
|
+
completedAt?: Date | null;
|
|
177
|
+
/** Type of study session */
|
|
178
|
+
type: ESessionType;
|
|
179
|
+
/** Difficulty level */
|
|
180
|
+
level: ILevel;
|
|
181
|
+
/** Algorithm configuration */
|
|
182
|
+
algorithm: EFlashcardAlgorithm;
|
|
183
|
+
/** Maximum new cards per session */
|
|
184
|
+
maxNewCards: number;
|
|
185
|
+
/** Maximum review cards per session */
|
|
186
|
+
maxReviewCards: number;
|
|
187
|
+
/** Desired retention rate (0-1) for FSRS */
|
|
188
|
+
desiredRetention: number;
|
|
189
|
+
/** Learning steps (in minutes) */
|
|
190
|
+
learningSteps: number[];
|
|
191
|
+
/** Graduating interval (in days) */
|
|
192
|
+
graduatingInterval: number;
|
|
193
|
+
/** Easy interval (in days) */
|
|
194
|
+
easyInterval: number;
|
|
195
|
+
/** Maximum interval (in days) */
|
|
196
|
+
maxInterval: number;
|
|
197
|
+
}
|
|
198
|
+
interface IFlashcardDeck extends IBase2 {
|
|
199
|
+
name: string;
|
|
200
|
+
description?: string;
|
|
201
|
+
/** Total cards in deck */
|
|
202
|
+
totalCards: number;
|
|
203
|
+
/** New cards ready to learn */
|
|
204
|
+
newCards: number;
|
|
205
|
+
/** Cards in learning phase */
|
|
206
|
+
learningCards: number;
|
|
207
|
+
/** Cards due for review today */
|
|
208
|
+
dueCards: number;
|
|
209
|
+
/** Cards suspended */
|
|
210
|
+
suspendedCards: number;
|
|
211
|
+
/** All flashcards in this deck */
|
|
212
|
+
cards: IFlashcard[];
|
|
213
|
+
/** Deck settings */
|
|
214
|
+
algorithm: EFlashcardAlgorithm;
|
|
215
|
+
maxNewCardsPerDay: number;
|
|
216
|
+
maxReviewCardsPerDay: number;
|
|
217
|
+
desiredRetention: number;
|
|
218
|
+
learningSteps: number[];
|
|
219
|
+
relearningSteps: number[];
|
|
220
|
+
graduatingInterval: number;
|
|
221
|
+
easyInterval: number;
|
|
222
|
+
maxInterval: number;
|
|
223
|
+
/** FSRS parameters (17 parameters) */
|
|
224
|
+
fsrsParameters?: number[];
|
|
225
|
+
/** Leech threshold (number of lapses before marking as leech) */
|
|
226
|
+
leechThreshold: number;
|
|
227
|
+
/** Whether to bury sibling cards */
|
|
228
|
+
burySiblings: boolean;
|
|
229
|
+
/** Deck statistics */
|
|
230
|
+
stat?: IStat;
|
|
231
|
+
status?: IStatus;
|
|
232
|
+
}
|
|
233
|
+
interface IFlashcardPreset extends IBase2 {
|
|
234
|
+
name: string;
|
|
235
|
+
description?: string;
|
|
236
|
+
/** Algorithm to use */
|
|
237
|
+
algorithm: EFlashcardAlgorithm;
|
|
238
|
+
/** Learning configuration */
|
|
239
|
+
learningSteps: number[];
|
|
240
|
+
relearningSteps: number[];
|
|
241
|
+
graduatingInterval: number;
|
|
242
|
+
easyInterval: number;
|
|
243
|
+
maxInterval: number;
|
|
244
|
+
/** Daily limits */
|
|
245
|
+
maxNewCardsPerDay: number;
|
|
246
|
+
maxReviewCardsPerDay: number;
|
|
247
|
+
/** FSRS configuration */
|
|
248
|
+
desiredRetention: number;
|
|
249
|
+
fsrsParameters?: number[];
|
|
250
|
+
/** SM-2 configuration */
|
|
251
|
+
startingEaseFactor: number;
|
|
252
|
+
easyBonus: number;
|
|
253
|
+
intervalModifier: number;
|
|
254
|
+
hardInterval: number;
|
|
255
|
+
newInterval: number;
|
|
256
|
+
/** Lapse configuration */
|
|
257
|
+
minimumInterval: number;
|
|
258
|
+
leechThreshold: number;
|
|
259
|
+
/** Display options */
|
|
260
|
+
burySiblings: boolean;
|
|
261
|
+
showTimer: boolean;
|
|
262
|
+
autoPlayAudio: boolean;
|
|
263
|
+
}
|
|
264
|
+
interface IFlashcardStats extends IBase2 {
|
|
265
|
+
/** Cards studied today */
|
|
266
|
+
cardsStudiedToday: number;
|
|
267
|
+
/** Time spent studying today (minutes) */
|
|
268
|
+
timeSpentToday: number;
|
|
269
|
+
/** Current streak (days) */
|
|
270
|
+
currentStreak: number;
|
|
271
|
+
/** Longest streak (days) */
|
|
272
|
+
longestStreak: number;
|
|
273
|
+
/** Total reviews all time */
|
|
274
|
+
totalReviews: number;
|
|
275
|
+
/** Total study time all time (minutes) */
|
|
276
|
+
totalStudyTime: number;
|
|
277
|
+
/** Average retention rate */
|
|
278
|
+
retentionRate: number;
|
|
279
|
+
/** Breakdown by card state */
|
|
280
|
+
newCardsCount: number;
|
|
281
|
+
learningCardsCount: number;
|
|
282
|
+
reviewCardsCount: number;
|
|
283
|
+
suspendedCardsCount: number;
|
|
284
|
+
/** Maturity statistics */
|
|
285
|
+
matureCardsCount: number;
|
|
286
|
+
youngCardsCount: number;
|
|
287
|
+
/** Performance by rating */
|
|
288
|
+
againCount: number;
|
|
289
|
+
hardCount: number;
|
|
290
|
+
goodCount: number;
|
|
291
|
+
easyCount: number;
|
|
292
|
+
/** Date range for these stats */
|
|
293
|
+
startDate: Date;
|
|
294
|
+
endDate: Date;
|
|
295
|
+
}
|
|
296
|
+
/**
|
|
297
|
+
* Base interface for spaced repetition algorithms
|
|
298
|
+
*/
|
|
299
|
+
interface ISpacedRepetitionAlgorithm {
|
|
300
|
+
/**
|
|
301
|
+
* Calculate the next review schedule for a card
|
|
302
|
+
*/
|
|
303
|
+
calculateNextReview: (card: IFlashcard, rating: EFlashcardRating, reviewTime: number) => IFlashcardSchedule;
|
|
304
|
+
/**
|
|
305
|
+
* Get the predicted intervals for each rating button
|
|
306
|
+
*/
|
|
307
|
+
getIntervalPreview: (card: IFlashcard) => Record<EFlashcardRating, number>;
|
|
308
|
+
/**
|
|
309
|
+
* Initialize a new card's schedule
|
|
310
|
+
*/
|
|
311
|
+
initializeCard: (learningSteps: number[]) => IFlashcardSchedule;
|
|
312
|
+
/**
|
|
313
|
+
* Get algorithm-specific parameters
|
|
314
|
+
*/
|
|
315
|
+
getParameters: () => Record<string, unknown>;
|
|
316
|
+
/**
|
|
317
|
+
* Update algorithm parameters
|
|
318
|
+
*/
|
|
319
|
+
setParameters: (parameters: Record<string, unknown>) => void;
|
|
320
|
+
}
|
|
321
|
+
/**
|
|
322
|
+
* SM-2 (SuperMemo 2) Algorithm Implementation Interface
|
|
323
|
+
*/
|
|
324
|
+
interface ISM2Algorithm extends ISpacedRepetitionAlgorithm {
|
|
325
|
+
/**
|
|
326
|
+
* SM-2 specific parameters
|
|
327
|
+
*/
|
|
328
|
+
getParameters: () => {
|
|
329
|
+
startingEaseFactor: number;
|
|
330
|
+
easyBonus: number;
|
|
331
|
+
intervalModifier: number;
|
|
332
|
+
hardInterval: number;
|
|
333
|
+
newInterval: number;
|
|
334
|
+
minimumInterval: number;
|
|
335
|
+
maxInterval: number;
|
|
336
|
+
graduatingInterval: number;
|
|
337
|
+
easyInterval: number;
|
|
338
|
+
};
|
|
339
|
+
/**
|
|
340
|
+
* Calculate ease factor adjustment
|
|
341
|
+
*/
|
|
342
|
+
calculateEaseAdjustment: (rating: EFlashcardRating, currentEase: number) => number;
|
|
343
|
+
/**
|
|
344
|
+
* Calculate interval for review cards
|
|
345
|
+
*/
|
|
346
|
+
calculateReviewInterval: (previousInterval: number, easeFactor: number, rating: EFlashcardRating) => number;
|
|
347
|
+
/**
|
|
348
|
+
* Handle learning phase transitions
|
|
349
|
+
*/
|
|
350
|
+
processLearningCard: (card: IFlashcard, rating: EFlashcardRating, learningSteps: number[]) => {
|
|
351
|
+
newState: EFlashcardState;
|
|
352
|
+
interval: number;
|
|
353
|
+
currentStep: number;
|
|
354
|
+
};
|
|
355
|
+
/**
|
|
356
|
+
* Handle lapse (forgotten card)
|
|
357
|
+
*/
|
|
358
|
+
processLapse: (card: IFlashcard, relearningSteps: number[]) => {
|
|
359
|
+
newState: EFlashcardState;
|
|
360
|
+
interval: number;
|
|
361
|
+
easeFactor: number;
|
|
362
|
+
currentStep: number;
|
|
363
|
+
};
|
|
364
|
+
}
|
|
365
|
+
/**
|
|
366
|
+
* FSRS (Free Spaced Repetition Scheduler) Algorithm Interface
|
|
367
|
+
*/
|
|
368
|
+
interface IFSRSAlgorithm extends ISpacedRepetitionAlgorithm {
|
|
369
|
+
/**
|
|
370
|
+
* FSRS specific parameters (17 parameters)
|
|
371
|
+
*/
|
|
372
|
+
getParameters: () => {
|
|
373
|
+
parameters: number[];
|
|
374
|
+
desiredRetention: number;
|
|
375
|
+
requestRetention: number;
|
|
376
|
+
maxInterval: number;
|
|
377
|
+
};
|
|
378
|
+
/**
|
|
379
|
+
* Calculate memory state (Difficulty, Stability, Retrievability)
|
|
380
|
+
*/
|
|
381
|
+
calculateMemoryState: (difficulty: number, stability: number, retrievability: number, rating: EFlashcardRating, deltaT: number) => {
|
|
382
|
+
newDifficulty: number;
|
|
383
|
+
newStability: number;
|
|
384
|
+
newRetrievability: number;
|
|
385
|
+
};
|
|
386
|
+
/**
|
|
387
|
+
* Calculate retrievability based on time elapsed
|
|
388
|
+
*/
|
|
389
|
+
calculateRetrievability: (stability: number, deltaT: number) => number;
|
|
390
|
+
/**
|
|
391
|
+
* Calculate next interval based on desired retention
|
|
392
|
+
*/
|
|
393
|
+
calculateInterval: (stability: number, desiredRetention: number) => number;
|
|
394
|
+
/**
|
|
395
|
+
* Initialize FSRS card state
|
|
396
|
+
*/
|
|
397
|
+
initializeFSRSCard: () => {
|
|
398
|
+
difficulty: number;
|
|
399
|
+
stability: number;
|
|
400
|
+
retrievability: number;
|
|
401
|
+
};
|
|
402
|
+
/**
|
|
403
|
+
* Optimize parameters based on review history
|
|
404
|
+
*/
|
|
405
|
+
optimizeParameters: (reviews: IFlashcardReview[]) => number[];
|
|
406
|
+
/**
|
|
407
|
+
* Evaluate parameter quality
|
|
408
|
+
*/
|
|
409
|
+
evaluateParameters: (reviews: IFlashcardReview[]) => {
|
|
410
|
+
logLoss: number;
|
|
411
|
+
rmse: number;
|
|
412
|
+
};
|
|
413
|
+
}
|
|
414
|
+
/**
|
|
415
|
+
* Algorithm factory for creating algorithm instances
|
|
416
|
+
*/
|
|
417
|
+
interface IAlgorithmFactory {
|
|
418
|
+
/**
|
|
419
|
+
* Create SM-2 algorithm instance
|
|
420
|
+
*/
|
|
421
|
+
createSM2Algorithm: (parameters?: Partial<ISM2Algorithm["getParameters"]>) => ISM2Algorithm;
|
|
422
|
+
/**
|
|
423
|
+
* Create FSRS algorithm instance
|
|
424
|
+
*/
|
|
425
|
+
createFSRSAlgorithm: (parameters?: Partial<IFSRSAlgorithm["getParameters"]>) => IFSRSAlgorithm;
|
|
426
|
+
/**
|
|
427
|
+
* Get default parameters for an algorithm
|
|
428
|
+
*/
|
|
429
|
+
getDefaultParameters: (algorithm: "sm2" | "fsrs") => Record<string, unknown>;
|
|
430
|
+
}
|
|
431
|
+
/**
|
|
432
|
+
* Algorithm utilities and helpers
|
|
433
|
+
*/
|
|
434
|
+
interface IAlgorithmUtils {
|
|
435
|
+
/**
|
|
436
|
+
* Apply fuzzing to interval (randomization)
|
|
437
|
+
*/
|
|
438
|
+
applyFuzzing: (interval: number, fuzzFactor?: number) => number;
|
|
439
|
+
/**
|
|
440
|
+
* Convert learning steps from minutes to intervals
|
|
441
|
+
*/
|
|
442
|
+
convertLearningSteps: (steps: number[]) => number[];
|
|
443
|
+
/**
|
|
444
|
+
* Calculate next due date
|
|
445
|
+
*/
|
|
446
|
+
calculateDueDate: (interval: number, baseDate?: Date) => Date;
|
|
447
|
+
/**
|
|
448
|
+
* Determine if interval should be fuzzed
|
|
449
|
+
*/
|
|
450
|
+
shouldApplyFuzzing: (interval: number) => boolean;
|
|
451
|
+
/**
|
|
452
|
+
* Clamp interval to valid range
|
|
453
|
+
*/
|
|
454
|
+
clampInterval: (interval: number, minInterval: number, maxInterval: number) => number;
|
|
455
|
+
/**
|
|
456
|
+
* Calculate average interval for multiple ratings
|
|
457
|
+
*/
|
|
458
|
+
calculateAverageInterval: (intervals: number[]) => number;
|
|
459
|
+
}
|
|
460
|
+
/**
|
|
461
|
+
* Review statistics calculator
|
|
462
|
+
*/
|
|
463
|
+
interface IReviewStats {
|
|
464
|
+
/**
|
|
465
|
+
* Calculate retention rate from reviews
|
|
466
|
+
*/
|
|
467
|
+
calculateRetention: (reviews: IFlashcardReview[]) => number;
|
|
468
|
+
/**
|
|
469
|
+
* Calculate average response time
|
|
470
|
+
*/
|
|
471
|
+
calculateAverageResponseTime: (reviews: IFlashcardReview[]) => number;
|
|
472
|
+
/**
|
|
473
|
+
* Get rating distribution
|
|
474
|
+
*/
|
|
475
|
+
getRatingDistribution: (reviews: IFlashcardReview[]) => Record<EFlashcardRating, number>;
|
|
476
|
+
/**
|
|
477
|
+
* Calculate study load (cards per day)
|
|
478
|
+
*/
|
|
479
|
+
calculateStudyLoad: (cards: IFlashcard[]) => {
|
|
480
|
+
newCards: number;
|
|
481
|
+
learningCards: number;
|
|
482
|
+
reviewCards: number;
|
|
483
|
+
total: number;
|
|
484
|
+
};
|
|
485
|
+
/**
|
|
486
|
+
* Predict future workload
|
|
487
|
+
*/
|
|
488
|
+
predictWorkload: (cards: IFlashcard[], algorithm: ISpacedRepetitionAlgorithm, days: number) => {
|
|
489
|
+
date: Date;
|
|
490
|
+
newCards: number;
|
|
491
|
+
reviews: number;
|
|
492
|
+
total: number;
|
|
493
|
+
}[];
|
|
494
|
+
}
|
|
495
|
+
/**
|
|
496
|
+
* Scheduler for managing card due dates and priorities
|
|
497
|
+
*/
|
|
498
|
+
interface ICardScheduler {
|
|
499
|
+
/**
|
|
500
|
+
* Get cards due for review
|
|
501
|
+
*/
|
|
502
|
+
getDueCards: (cards: IFlashcard[], maxCards?: number) => IFlashcard[];
|
|
503
|
+
/**
|
|
504
|
+
* Get new cards ready for learning
|
|
505
|
+
*/
|
|
506
|
+
getNewCards: (cards: IFlashcard[], maxCards?: number) => IFlashcard[];
|
|
507
|
+
/**
|
|
508
|
+
* Get learning cards ready for next step
|
|
509
|
+
*/
|
|
510
|
+
getLearningCards: (cards: IFlashcard[]) => IFlashcard[];
|
|
511
|
+
/**
|
|
512
|
+
* Sort cards by priority
|
|
513
|
+
*/
|
|
514
|
+
sortCardsByPriority: (cards: IFlashcard[], sortOrder: "due" | "random" | "added") => IFlashcard[];
|
|
515
|
+
/**
|
|
516
|
+
* Check if card is overdue
|
|
517
|
+
*/
|
|
518
|
+
isOverdue: (card: IFlashcard) => boolean;
|
|
519
|
+
/**
|
|
520
|
+
* Calculate overdue factor
|
|
521
|
+
*/
|
|
522
|
+
getOverdueFactor: (card: IFlashcard) => number;
|
|
523
|
+
/**
|
|
524
|
+
* Reschedule all cards with new algorithm
|
|
525
|
+
*/
|
|
526
|
+
rescheduleCards: (cards: IFlashcard[], algorithm: ISpacedRepetitionAlgorithm) => IFlashcard[];
|
|
527
|
+
}
|
|
528
|
+
/**
|
|
529
|
+
* Default Anki algorithm constants
|
|
530
|
+
*/
|
|
531
|
+
declare const ANKI_DEFAULTS: {
|
|
532
|
+
readonly LEARNING_STEPS: readonly [1, 10];
|
|
533
|
+
readonly GRADUATING_INTERVAL: 1;
|
|
534
|
+
readonly EASY_INTERVAL: 4;
|
|
535
|
+
readonly STARTING_EASE_FACTOR: 2.5;
|
|
536
|
+
readonly EASY_BONUS: 1.3;
|
|
537
|
+
readonly INTERVAL_MODIFIER: 1.0;
|
|
538
|
+
readonly HARD_INTERVAL: 1.2;
|
|
539
|
+
readonly RELEARNING_STEPS: readonly [10];
|
|
540
|
+
readonly NEW_INTERVAL: 0.0;
|
|
541
|
+
readonly MINIMUM_INTERVAL: 1;
|
|
542
|
+
readonly LEECH_THRESHOLD: 8;
|
|
543
|
+
readonly MAX_NEW_CARDS_PER_DAY: 20;
|
|
544
|
+
readonly MAX_REVIEW_CARDS_PER_DAY: 200;
|
|
545
|
+
readonly MAX_ANSWER_TIME: 60;
|
|
546
|
+
readonly MIN_INTERVAL: 1;
|
|
547
|
+
readonly MAX_INTERVAL: 36500;
|
|
548
|
+
readonly DESIRED_RETENTION: 0.9;
|
|
549
|
+
readonly FSRS_DEFAULT_PARAMETERS: readonly [0.4072, 1.1829, 3.1262, 15.4722, 7.2102, 0.5316, 1.0651, 0.0234, 1.616, 0.1544, 1.0824, 1.9813, 0.0953, 0.2975, 2.2042, 0.2407, 2.9466];
|
|
550
|
+
};
|
|
551
|
+
/**
|
|
552
|
+
* Rating multipliers for interval calculation
|
|
553
|
+
*/
|
|
554
|
+
declare const RATING_MULTIPLIERS: Record<EFlashcardRating, number>;
|
|
555
|
+
/**
|
|
556
|
+
* Ease factor adjustments based on rating
|
|
557
|
+
*/
|
|
558
|
+
declare const EASE_ADJUSTMENTS: Record<EFlashcardRating, number>;
|
|
559
|
+
/**
|
|
560
|
+
* Minimum and maximum ease factor bounds
|
|
561
|
+
*/
|
|
562
|
+
declare const EASE_BOUNDS: {
|
|
563
|
+
readonly MIN: 1.3;
|
|
564
|
+
readonly MAX: 2.5;
|
|
565
|
+
};
|
|
566
|
+
/**
|
|
567
|
+
* Card state transitions based on rating
|
|
568
|
+
*/
|
|
569
|
+
declare const STATE_TRANSITIONS: Record<EFlashcardState, Record<EFlashcardRating, EFlashcardState>>;
|
|
570
|
+
/**
|
|
571
|
+
* Learning step multipliers for Hard button
|
|
572
|
+
*/
|
|
573
|
+
declare const LEARNING_HARD_MULTIPLIERS: {
|
|
574
|
+
readonly FIRST_STEP: 1.5;
|
|
575
|
+
readonly AVERAGE_STEPS: 0.5;
|
|
576
|
+
};
|
|
577
|
+
/**
|
|
578
|
+
* Fuzz factor for randomizing intervals
|
|
579
|
+
*/
|
|
580
|
+
declare const FUZZ_FACTOR: {
|
|
581
|
+
readonly MIN: 0.95;
|
|
582
|
+
readonly MAX: 1.05;
|
|
583
|
+
};
|
|
584
|
+
/**
|
|
585
|
+
* Session scoring weights
|
|
586
|
+
*/
|
|
587
|
+
declare const SCORE_WEIGHTS: Record<EFlashcardRating, number>;
|
|
588
|
+
/**
|
|
589
|
+
* Card maturity threshold (days)
|
|
590
|
+
*/
|
|
591
|
+
declare const MATURITY_THRESHOLD = 21;
|
|
592
|
+
/**
|
|
593
|
+
* Default preset configurations
|
|
594
|
+
*/
|
|
595
|
+
declare const DEFAULT_PRESETS: {
|
|
596
|
+
readonly BEGINNER: {
|
|
597
|
+
readonly name: "Beginner";
|
|
598
|
+
readonly description: "For new learners with more repetition";
|
|
599
|
+
readonly learningSteps: readonly [1, 10, 1440];
|
|
600
|
+
readonly graduatingInterval: 2;
|
|
601
|
+
readonly easyInterval: 7;
|
|
602
|
+
readonly maxNewCardsPerDay: 10;
|
|
603
|
+
readonly desiredRetention: 0.85;
|
|
604
|
+
};
|
|
605
|
+
readonly DEFAULT: {
|
|
606
|
+
readonly name: "Default";
|
|
607
|
+
readonly description: "Balanced settings for most users";
|
|
608
|
+
readonly learningSteps: readonly [1, 10];
|
|
609
|
+
readonly graduatingInterval: 1;
|
|
610
|
+
readonly easyInterval: 4;
|
|
611
|
+
readonly maxNewCardsPerDay: 20;
|
|
612
|
+
readonly desiredRetention: 0.9;
|
|
613
|
+
};
|
|
614
|
+
readonly INTENSIVE: {
|
|
615
|
+
readonly name: "Intensive";
|
|
616
|
+
readonly description: "For serious learners who want higher retention";
|
|
617
|
+
readonly learningSteps: readonly [1, 10];
|
|
618
|
+
readonly graduatingInterval: 1;
|
|
619
|
+
readonly easyInterval: 4;
|
|
620
|
+
readonly maxNewCardsPerDay: 30;
|
|
621
|
+
readonly desiredRetention: 0.95;
|
|
622
|
+
};
|
|
623
|
+
readonly LIGHT: {
|
|
624
|
+
readonly name: "Light";
|
|
625
|
+
readonly description: "For casual learning with fewer reviews";
|
|
626
|
+
readonly learningSteps: readonly [1, 10];
|
|
627
|
+
readonly graduatingInterval: 3;
|
|
628
|
+
readonly easyInterval: 7;
|
|
629
|
+
readonly maxNewCardsPerDay: 15;
|
|
630
|
+
readonly desiredRetention: 0.8;
|
|
631
|
+
};
|
|
632
|
+
};
|
|
633
|
+
/**
|
|
634
|
+
* Algorithm-specific constants
|
|
635
|
+
*/
|
|
636
|
+
interface SM2Constants {
|
|
637
|
+
MIN_EASE_FACTOR: number;
|
|
638
|
+
MAX_EASE_FACTOR: number;
|
|
639
|
+
EASE_ADJUSTMENT_STEP: number;
|
|
640
|
+
}
|
|
641
|
+
interface FSRSConstants {
|
|
642
|
+
MIN_DIFFICULTY: number;
|
|
643
|
+
MAX_DIFFICULTY: number;
|
|
644
|
+
MIN_STABILITY: number;
|
|
645
|
+
MAX_STABILITY: number;
|
|
646
|
+
MIN_RETRIEVABILITY: number;
|
|
647
|
+
MAX_RETRIEVABILITY: number;
|
|
648
|
+
}
|
|
649
|
+
type AlgorithmConstants = {
|
|
650
|
+
[EFlashcardAlgorithm.SM2]: SM2Constants;
|
|
651
|
+
[EFlashcardAlgorithm.FSRS]: FSRSConstants;
|
|
652
|
+
};
|
|
653
|
+
declare const ALGORITHM_CONSTANTS: AlgorithmConstants;
|
|
654
|
+
/**
|
|
655
|
+
* Utility functions for common calculations
|
|
656
|
+
*/
|
|
657
|
+
declare const UTILS: {
|
|
658
|
+
/**
|
|
659
|
+
* Convert minutes to milliseconds
|
|
660
|
+
*/
|
|
661
|
+
readonly minutesToMs: (minutes: number) => number;
|
|
662
|
+
/**
|
|
663
|
+
* Convert days to milliseconds
|
|
664
|
+
*/
|
|
665
|
+
readonly daysToMs: (days: number) => number;
|
|
666
|
+
/**
|
|
667
|
+
* Apply fuzz factor to interval
|
|
668
|
+
*/
|
|
669
|
+
readonly applyFuzz: (interval: number) => number;
|
|
670
|
+
/**
|
|
671
|
+
* Clamp ease factor to valid range
|
|
672
|
+
*/
|
|
673
|
+
readonly clampEaseFactor: (ease: number) => number;
|
|
674
|
+
/**
|
|
675
|
+
* Calculate session score
|
|
676
|
+
*/
|
|
677
|
+
readonly calculateScore: (ratings: EFlashcardRating[]) => number;
|
|
678
|
+
/**
|
|
679
|
+
* Determine if card is mature
|
|
680
|
+
*/
|
|
681
|
+
readonly isMature: (interval: number) => boolean;
|
|
682
|
+
};
|
|
683
|
+
export { UTILS, STATE_TRANSITIONS, SCORE_WEIGHTS, RATING_MULTIPLIERS, MATURITY_THRESHOLD, LEARNING_HARD_MULTIPLIERS, ISpacedRepetitionAlgorithm, ISM2Algorithm, IReviewStats, IFlashcardStats, IFlashcardSession, IFlashcardSchedule, IFlashcardReview, IFlashcardPreset, IFlashcardDeck, IFlashcard, IFSRSAlgorithm, ICardScheduler, IAlgorithmUtils, IAlgorithmFactory, FUZZ_FACTOR, EFlashcardState, EFlashcardSessionStatus, EFlashcardRating, EFlashcardAlgorithm, EASE_BOUNDS, EASE_ADJUSTMENTS, DEFAULT_PRESETS, ANKI_DEFAULTS, ALGORITHM_CONSTANTS };
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
var J;((f)=>{f.NEW="new";f.LEARNING="learning";f.RELEARNING="relearning";f.REVIEW="review";f.BURIED="buried";f.SUSPENDED="suspended"})(J||={});var K;((x)=>{x.AGAIN="again";x.HARD="hard";x.GOOD="good";x.EASY="easy"})(K||={});var b;((x)=>{x.DRAFT="draft";x.STARTED="started";x.PAUSED="paused";x.COMPLETED="completed"})(b||={});var Q;((j)=>{j.SM2="sm2";j.FSRS="fsrs"})(Q||={});var w={LEARNING_STEPS:[1,10],GRADUATING_INTERVAL:1,EASY_INTERVAL:4,STARTING_EASE_FACTOR:2.5,EASY_BONUS:1.3,INTERVAL_MODIFIER:1,HARD_INTERVAL:1.2,RELEARNING_STEPS:[10],NEW_INTERVAL:0,MINIMUM_INTERVAL:1,LEECH_THRESHOLD:8,MAX_NEW_CARDS_PER_DAY:20,MAX_REVIEW_CARDS_PER_DAY:200,MAX_ANSWER_TIME:60,MIN_INTERVAL:1,MAX_INTERVAL:36500,DESIRED_RETENTION:0.9,FSRS_DEFAULT_PARAMETERS:[0.4072,1.1829,3.1262,15.4722,7.2102,0.5316,1.0651,0.0234,1.616,0.1544,1.0824,1.9813,0.0953,0.2975,2.2042,0.2407,2.9466]},z=Object.freeze({again:0,hard:1.2,good:2.5,easy:3.25}),B=Object.freeze({again:-0.2,hard:-0.15,good:0,easy:0.15}),V={MIN:1.3,MAX:2.5},G=Object.freeze({new:Object.freeze({again:"learning",hard:"learning",good:"learning",easy:"review"}),learning:Object.freeze({again:"learning",hard:"learning",good:"learning",easy:"review"}),review:Object.freeze({again:"relearning",hard:"review",good:"review",easy:"review"}),relearning:Object.freeze({again:"relearning",hard:"relearning",good:"relearning",easy:"review"}),buried:Object.freeze({again:"buried",hard:"buried",good:"buried",easy:"buried"}),suspended:Object.freeze({again:"suspended",hard:"suspended",good:"suspended",easy:"suspended"})}),N={FIRST_STEP:1.5,AVERAGE_STEPS:0.5},q={MIN:0.95,MAX:1.05},X=Object.freeze({again:0,hard:50,good:80,easy:100}),L=21,P={BEGINNER:{name:"Beginner",description:"For new learners with more repetition",learningSteps:[1,10,1440],graduatingInterval:2,easyInterval:7,maxNewCardsPerDay:10,desiredRetention:0.85},DEFAULT:{name:"Default",description:"Balanced settings for most users",learningSteps:[1,10],graduatingInterval:1,easyInterval:4,maxNewCardsPerDay:20,desiredRetention:0.9},INTENSIVE:{name:"Intensive",description:"For serious learners who want higher retention",learningSteps:[1,10],graduatingInterval:1,easyInterval:4,maxNewCardsPerDay:30,desiredRetention:0.95},LIGHT:{name:"Light",description:"For casual learning with fewer reviews",learningSteps:[1,10],graduatingInterval:3,easyInterval:7,maxNewCardsPerDay:15,desiredRetention:0.8}},W=Object.freeze({sm2:Object.freeze({MIN_EASE_FACTOR:1.3,MAX_EASE_FACTOR:2.5,EASE_ADJUSTMENT_STEP:0.15}),fsrs:Object.freeze({MIN_DIFFICULTY:1,MAX_DIFFICULTY:10,MIN_STABILITY:0.1,MAX_STABILITY:36500,MIN_RETRIEVABILITY:0.01,MAX_RETRIEVABILITY:0.99})}),y={minutesToMs:(p)=>p*60*1000,daysToMs:(p)=>p*24*60*60*1000,applyFuzz:(p)=>{let k=q.MIN+Math.random()*(q.MAX-q.MIN);return Math.max(1,Math.round(p*k))},clampEaseFactor:(p)=>{return Math.max(V.MIN,Math.min(p,V.MAX))},calculateScore:(p)=>{if(p.length===0)return 0;let k=p.reduce(($,x)=>$+X[x],0),j=p.length*X["easy"];return Math.round(k/j*100)},isMature:(p)=>p>=L};export{y as UTILS,G as STATE_TRANSITIONS,X as SCORE_WEIGHTS,z as RATING_MULTIPLIERS,L as MATURITY_THRESHOLD,N as LEARNING_HARD_MULTIPLIERS,q as FUZZ_FACTOR,J as EFlashcardState,b as EFlashcardSessionStatus,K as EFlashcardRating,Q as EFlashcardAlgorithm,V as EASE_BOUNDS,B as EASE_ADJUSTMENTS,P as DEFAULT_PRESETS,w as ANKI_DEFAULTS,W as ALGORITHM_CONSTANTS};
|
|
2
|
+
|
|
3
|
+
//# debugId=38A76FAEB9774D5664756E2164756E21
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["src/flashcard/types.ts", "src/flashcard/constants.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"import type { IImage } from \"@ooneex/image\";\nimport type { IStatus } from \"@ooneex/status\";\nimport type { ITag } from \"@ooneex/tag\";\nimport type { IBase, IStat } from \"@ooneex/types\";\nimport type { ESessionType, ILevel } from \"../types\";\n\nexport enum EFlashcardState {\n /** Brand new card that hasn't been studied yet */\n NEW = \"new\",\n /** Card in learning phase with short intervals */\n LEARNING = \"learning\",\n /** Card in relearning phase after being forgotten */\n RELEARNING = \"relearning\",\n /** Graduated card in long-term review cycle */\n REVIEW = \"review\",\n /** Card temporarily hidden until next day */\n BURIED = \"buried\",\n /** Card permanently hidden from reviews */\n SUSPENDED = \"suspended\",\n}\n\nexport enum EFlashcardRating {\n /** Incorrect answer - restart learning */\n AGAIN = \"again\",\n /** Correct but difficult - shorter interval */\n HARD = \"hard\",\n /** Correct with some effort - normal interval */\n GOOD = \"good\",\n /** Correct with no effort - longer interval */\n EASY = \"easy\",\n}\n\nexport enum EFlashcardSessionStatus {\n DRAFT = \"draft\",\n STARTED = \"started\",\n PAUSED = \"paused\",\n COMPLETED = \"completed\",\n}\n\nexport enum EFlashcardAlgorithm {\n /** Legacy SuperMemo 2 algorithm */\n SM2 = \"sm2\",\n /** Free Spaced Repetition Scheduler (modern) */\n FSRS = \"fsrs\",\n}\n\nexport interface IFlashcardSchedule extends IBase {\n /** Current state of the card */\n state: EFlashcardState;\n /** Days until next review */\n interval: number;\n /** Ease factor for SM-2 algorithm (2.5 = 250%) */\n easeFactor: number;\n /** Number of times card has been reviewed */\n reviewCount: number;\n /** Number of times card has failed (lapses) */\n lapseCount: number;\n /** Current step in learning/relearning sequence */\n currentStep: number;\n /** When the card is due for review */\n dueDate: Date;\n /** Last time the card was reviewed */\n lastReviewedAt?: Date | null;\n /** FSRS-specific parameters */\n difficulty?: number; // FSRS difficulty (0-10)\n stability?: number; // FSRS stability in days\n retrievability?: number; // FSRS retrievability (0-1)\n /** Learning steps for this card (in minutes) */\n learningSteps: number[];\n /** Relearning steps for this card (in minutes) */\n relearningSteps: number[];\n}\n\nexport interface IFlashcard extends IBase {\n /** Front side content */\n front: string;\n /** Back side content */\n back: string;\n /** Optional hint text */\n hint?: string;\n /** Optional context or source */\n context?: string;\n contextId?: string;\n /** Scheduling information */\n schedule: IFlashcardSchedule;\n /** Additional metadata */\n tags?: ITag[];\n stat?: IStat;\n status?: IStatus;\n image?: IImage;\n}\n\nexport interface IFlashcardReview extends IBase {\n /** The flashcard being reviewed */\n card: IFlashcard;\n /** Session this review belongs to */\n session: IFlashcardSession;\n /** User's rating for this review */\n rating: EFlashcardRating;\n /** Time taken to answer (in seconds) */\n responseTime: number;\n /** Previous interval before this review */\n previousInterval: number;\n /** New interval after this review */\n newInterval: number;\n /** Previous ease factor */\n previousEaseFactor: number;\n /** New ease factor */\n newEaseFactor: number;\n /** Previous due date */\n previousDueDate: Date;\n /** New due date */\n newDueDate: Date;\n /** Previous card state */\n previousState: EFlashcardState;\n /** New card state */\n newState: EFlashcardState;\n /** Whether this was a lapse (forgotten card) */\n wasLapse: boolean;\n /** Algorithm used for scheduling */\n algorithm: EFlashcardAlgorithm;\n /** Review timestamp */\n reviewedAt: Date;\n}\n\nexport interface IFlashcardSession extends IBase {\n name: string;\n /** Total cards available for study */\n totalCards: number;\n /** Number of new cards in session */\n newCardsCount: number;\n /** Number of learning cards in session */\n learningCardsCount: number;\n /** Number of review cards in session */\n reviewCardsCount: number;\n /** Cards studied so far */\n studiedCount: number;\n /** Cards answered correctly */\n correctCount: number;\n /** Cards answered incorrectly */\n incorrectCount: number;\n /** Total study time in seconds */\n studyTime: number;\n /** Cards in this session */\n cards: IFlashcard[];\n /** Reviews completed in this session */\n reviews: IFlashcardReview[];\n /** Session status */\n status: EFlashcardSessionStatus;\n /** Overall session score (0-100) */\n score: number;\n /** Session start time */\n startedAt?: Date | null;\n /** Session pause time */\n pausedAt?: Date | null;\n /** Session resume time */\n resumedAt?: Date | null;\n /** Session completion time */\n completedAt?: Date | null;\n /** Type of study session */\n type: ESessionType;\n /** Difficulty level */\n level: ILevel;\n /** Algorithm configuration */\n algorithm: EFlashcardAlgorithm;\n /** Maximum new cards per session */\n maxNewCards: number;\n /** Maximum review cards per session */\n maxReviewCards: number;\n /** Desired retention rate (0-1) for FSRS */\n desiredRetention: number;\n /** Learning steps (in minutes) */\n learningSteps: number[];\n /** Graduating interval (in days) */\n graduatingInterval: number;\n /** Easy interval (in days) */\n easyInterval: number;\n /** Maximum interval (in days) */\n maxInterval: number;\n}\n\nexport interface IFlashcardDeck extends IBase {\n name: string;\n description?: string;\n /** Total cards in deck */\n totalCards: number;\n /** New cards ready to learn */\n newCards: number;\n /** Cards in learning phase */\n learningCards: number;\n /** Cards due for review today */\n dueCards: number;\n /** Cards suspended */\n suspendedCards: number;\n /** All flashcards in this deck */\n cards: IFlashcard[];\n /** Deck settings */\n algorithm: EFlashcardAlgorithm;\n maxNewCardsPerDay: number;\n maxReviewCardsPerDay: number;\n desiredRetention: number;\n learningSteps: number[];\n relearningSteps: number[];\n graduatingInterval: number;\n easyInterval: number;\n maxInterval: number;\n /** FSRS parameters (17 parameters) */\n fsrsParameters?: number[];\n /** Leech threshold (number of lapses before marking as leech) */\n leechThreshold: number;\n /** Whether to bury sibling cards */\n burySiblings: boolean;\n /** Deck statistics */\n stat?: IStat;\n status?: IStatus;\n}\n\nexport interface IFlashcardPreset extends IBase {\n name: string;\n description?: string;\n /** Algorithm to use */\n algorithm: EFlashcardAlgorithm;\n /** Learning configuration */\n learningSteps: number[];\n relearningSteps: number[];\n graduatingInterval: number;\n easyInterval: number;\n maxInterval: number;\n /** Daily limits */\n maxNewCardsPerDay: number;\n maxReviewCardsPerDay: number;\n /** FSRS configuration */\n desiredRetention: number;\n fsrsParameters?: number[];\n /** SM-2 configuration */\n startingEaseFactor: number;\n easyBonus: number;\n intervalModifier: number;\n hardInterval: number;\n newInterval: number;\n /** Lapse configuration */\n minimumInterval: number;\n leechThreshold: number;\n /** Display options */\n burySiblings: boolean;\n showTimer: boolean;\n autoPlayAudio: boolean;\n}\n\nexport interface IFlashcardStats extends IBase {\n /** Cards studied today */\n cardsStudiedToday: number;\n /** Time spent studying today (minutes) */\n timeSpentToday: number;\n /** Current streak (days) */\n currentStreak: number;\n /** Longest streak (days) */\n longestStreak: number;\n /** Total reviews all time */\n totalReviews: number;\n /** Total study time all time (minutes) */\n totalStudyTime: number;\n /** Average retention rate */\n retentionRate: number;\n /** Breakdown by card state */\n newCardsCount: number;\n learningCardsCount: number;\n reviewCardsCount: number;\n suspendedCardsCount: number;\n /** Maturity statistics */\n matureCardsCount: number; // Cards with interval >= 21 days\n youngCardsCount: number; // Cards with interval < 21 days\n /** Performance by rating */\n againCount: number;\n hardCount: number;\n goodCount: number;\n easyCount: number;\n /** Date range for these stats */\n startDate: Date;\n endDate: Date;\n}\n",
|
|
6
|
+
"import { EFlashcardAlgorithm, EFlashcardRating, EFlashcardState } from \"./types\";\n\n/**\n * Default Anki algorithm constants\n */\nexport const ANKI_DEFAULTS = {\n // Learning phase\n LEARNING_STEPS: [1, 10], // 1 minute, 10 minutes\n GRADUATING_INTERVAL: 1, // 1 day\n EASY_INTERVAL: 4, // 4 days\n\n // Review phase (SM-2)\n STARTING_EASE_FACTOR: 2.5, // 250%\n EASY_BONUS: 1.3, // 130%\n INTERVAL_MODIFIER: 1.0, // 100%\n HARD_INTERVAL: 1.2, // 120%\n\n // Lapses\n RELEARNING_STEPS: [10], // 10 minutes\n NEW_INTERVAL: 0.0, // 0% of previous interval\n MINIMUM_INTERVAL: 1, // 1 day\n LEECH_THRESHOLD: 8, // 8 lapses\n\n // Daily limits\n MAX_NEW_CARDS_PER_DAY: 20,\n MAX_REVIEW_CARDS_PER_DAY: 200,\n\n // Timing\n MAX_ANSWER_TIME: 60, // 60 seconds\n MIN_INTERVAL: 1, // 1 day minimum\n MAX_INTERVAL: 36500, // 100 years\n\n // FSRS\n DESIRED_RETENTION: 0.9, // 90%\n FSRS_DEFAULT_PARAMETERS: [\n 0.4072, 1.1829, 3.1262, 15.4722, 7.2102, 0.5316, 1.0651, 0.0234, 1.616, 0.1544, 1.0824, 1.9813, 0.0953, 0.2975,\n 2.2042, 0.2407, 2.9466,\n ],\n} as const;\n\n/**\n * Rating multipliers for interval calculation\n */\nexport const RATING_MULTIPLIERS: Record<EFlashcardRating, number> = Object.freeze({\n [EFlashcardRating.AGAIN]: 0, // Reset to learning\n [EFlashcardRating.HARD]: 1.2,\n [EFlashcardRating.GOOD]: 2.5, // Default ease factor\n [EFlashcardRating.EASY]: 2.5 * 1.3, // Easy bonus applied\n});\n\n/**\n * Ease factor adjustments based on rating\n */\nexport const EASE_ADJUSTMENTS: Record<EFlashcardRating, number> = Object.freeze({\n [EFlashcardRating.AGAIN]: -0.2, // Decrease ease by 20%\n [EFlashcardRating.HARD]: -0.15, // Decrease ease by 15%\n [EFlashcardRating.GOOD]: 0, // No change\n [EFlashcardRating.EASY]: 0.15, // Increase ease by 15%\n});\n\n/**\n * Minimum and maximum ease factor bounds\n */\nexport const EASE_BOUNDS = {\n MIN: 1.3, // 130% minimum\n MAX: 2.5, // 250% maximum (no upper bound in practice)\n} as const;\n\n/**\n * Card state transitions based on rating\n */\nexport const STATE_TRANSITIONS: Record<EFlashcardState, Record<EFlashcardRating, EFlashcardState>> = Object.freeze({\n [EFlashcardState.NEW]: Object.freeze({\n [EFlashcardRating.AGAIN]: EFlashcardState.LEARNING,\n [EFlashcardRating.HARD]: EFlashcardState.LEARNING,\n [EFlashcardRating.GOOD]: EFlashcardState.LEARNING,\n [EFlashcardRating.EASY]: EFlashcardState.REVIEW,\n }),\n [EFlashcardState.LEARNING]: Object.freeze({\n [EFlashcardRating.AGAIN]: EFlashcardState.LEARNING, // Restart learning\n [EFlashcardRating.HARD]: EFlashcardState.LEARNING, // Repeat current step\n [EFlashcardRating.GOOD]: EFlashcardState.LEARNING, // Next step or graduate\n [EFlashcardRating.EASY]: EFlashcardState.REVIEW, // Skip to review\n }),\n [EFlashcardState.REVIEW]: Object.freeze({\n [EFlashcardRating.AGAIN]: EFlashcardState.RELEARNING,\n [EFlashcardRating.HARD]: EFlashcardState.REVIEW,\n [EFlashcardRating.GOOD]: EFlashcardState.REVIEW,\n [EFlashcardRating.EASY]: EFlashcardState.REVIEW,\n }),\n [EFlashcardState.RELEARNING]: Object.freeze({\n [EFlashcardRating.AGAIN]: EFlashcardState.RELEARNING, // Restart relearning\n [EFlashcardRating.HARD]: EFlashcardState.RELEARNING, // Repeat current step\n [EFlashcardRating.GOOD]: EFlashcardState.RELEARNING, // Next step or back to review\n [EFlashcardRating.EASY]: EFlashcardState.REVIEW, // Skip to review\n }),\n [EFlashcardState.BURIED]: Object.freeze({\n [EFlashcardRating.AGAIN]: EFlashcardState.BURIED, // Remains buried\n [EFlashcardRating.HARD]: EFlashcardState.BURIED, // Remains buried\n [EFlashcardRating.GOOD]: EFlashcardState.BURIED, // Remains buried\n [EFlashcardRating.EASY]: EFlashcardState.BURIED, // Remains buried\n }),\n [EFlashcardState.SUSPENDED]: Object.freeze({\n [EFlashcardRating.AGAIN]: EFlashcardState.SUSPENDED, // Remains suspended\n [EFlashcardRating.HARD]: EFlashcardState.SUSPENDED, // Remains suspended\n [EFlashcardRating.GOOD]: EFlashcardState.SUSPENDED, // Remains suspended\n [EFlashcardRating.EASY]: EFlashcardState.SUSPENDED, // Remains suspended\n }),\n});\n\n/**\n * Learning step multipliers for Hard button\n */\nexport const LEARNING_HARD_MULTIPLIERS = {\n FIRST_STEP: 1.5, // 150% of first step when only one step\n AVERAGE_STEPS: 0.5, // 50% of average between current and next step\n} as const;\n\n/**\n * Fuzz factor for randomizing intervals\n */\nexport const FUZZ_FACTOR = {\n MIN: 0.95, // 95% of calculated interval\n MAX: 1.05, // 105% of calculated interval\n} as const;\n\n/**\n * Session scoring weights\n */\nexport const SCORE_WEIGHTS: Record<EFlashcardRating, number> = Object.freeze({\n [EFlashcardRating.AGAIN]: 0, // 0 points\n [EFlashcardRating.HARD]: 50, // 50 points\n [EFlashcardRating.GOOD]: 80, // 80 points\n [EFlashcardRating.EASY]: 100, // 100 points\n});\n\n/**\n * Card maturity threshold (days)\n */\nexport const MATURITY_THRESHOLD = 21; // Cards with interval >= 21 days are mature\n\n/**\n * Default preset configurations\n */\nexport const DEFAULT_PRESETS = {\n BEGINNER: {\n name: \"Beginner\",\n description: \"For new learners with more repetition\",\n learningSteps: [1, 10, 1440], // 1m, 10m, 1d\n graduatingInterval: 2,\n easyInterval: 7,\n maxNewCardsPerDay: 10,\n desiredRetention: 0.85,\n },\n DEFAULT: {\n name: \"Default\",\n description: \"Balanced settings for most users\",\n learningSteps: [1, 10], // 1m, 10m\n graduatingInterval: 1,\n easyInterval: 4,\n maxNewCardsPerDay: 20,\n desiredRetention: 0.9,\n },\n INTENSIVE: {\n name: \"Intensive\",\n description: \"For serious learners who want higher retention\",\n learningSteps: [1, 10], // 1m, 10m\n graduatingInterval: 1,\n easyInterval: 4,\n maxNewCardsPerDay: 30,\n desiredRetention: 0.95,\n },\n LIGHT: {\n name: \"Light\",\n description: \"For casual learning with fewer reviews\",\n learningSteps: [1, 10], // 1m, 10m\n graduatingInterval: 3,\n easyInterval: 7,\n maxNewCardsPerDay: 15,\n desiredRetention: 0.8,\n },\n} as const;\n\n/**\n * Algorithm-specific constants\n */\ninterface SM2Constants {\n MIN_EASE_FACTOR: number;\n MAX_EASE_FACTOR: number;\n EASE_ADJUSTMENT_STEP: number;\n}\n\ninterface FSRSConstants {\n MIN_DIFFICULTY: number;\n MAX_DIFFICULTY: number;\n MIN_STABILITY: number;\n MAX_STABILITY: number;\n MIN_RETRIEVABILITY: number;\n MAX_RETRIEVABILITY: number;\n}\n\ntype AlgorithmConstants = {\n [EFlashcardAlgorithm.SM2]: SM2Constants;\n [EFlashcardAlgorithm.FSRS]: FSRSConstants;\n};\n\nexport const ALGORITHM_CONSTANTS: AlgorithmConstants = Object.freeze({\n [EFlashcardAlgorithm.SM2]: Object.freeze({\n MIN_EASE_FACTOR: 1.3,\n MAX_EASE_FACTOR: 2.5,\n EASE_ADJUSTMENT_STEP: 0.15,\n }),\n [EFlashcardAlgorithm.FSRS]: Object.freeze({\n MIN_DIFFICULTY: 1,\n MAX_DIFFICULTY: 10,\n MIN_STABILITY: 0.1,\n MAX_STABILITY: 36500,\n MIN_RETRIEVABILITY: 0.01,\n MAX_RETRIEVABILITY: 0.99,\n }),\n});\n\n/**\n * Utility functions for common calculations\n */\nexport const UTILS = {\n /**\n * Convert minutes to milliseconds\n */\n minutesToMs: (minutes: number): number => minutes * 60 * 1000,\n\n /**\n * Convert days to milliseconds\n */\n daysToMs: (days: number): number => days * 24 * 60 * 60 * 1000,\n\n /**\n * Apply fuzz factor to interval\n */\n applyFuzz: (interval: number): number => {\n const fuzz = FUZZ_FACTOR.MIN + Math.random() * (FUZZ_FACTOR.MAX - FUZZ_FACTOR.MIN);\n return Math.max(1, Math.round(interval * fuzz));\n },\n\n /**\n * Clamp ease factor to valid range\n */\n clampEaseFactor: (ease: number): number => {\n return Math.max(EASE_BOUNDS.MIN, Math.min(ease, EASE_BOUNDS.MAX));\n },\n\n /**\n * Calculate session score\n */\n calculateScore: (ratings: EFlashcardRating[]): number => {\n if (ratings.length === 0) return 0;\n const totalPoints = ratings.reduce((sum, rating) => sum + SCORE_WEIGHTS[rating], 0);\n const maxPossible = ratings.length * SCORE_WEIGHTS[EFlashcardRating.EASY];\n return Math.round((totalPoints / maxPossible) * 100);\n },\n\n /**\n * Determine if card is mature\n */\n isMature: (interval: number): boolean => interval >= MATURITY_THRESHOLD,\n} as const;\n"
|
|
7
|
+
],
|
|
8
|
+
"mappings": "AAMO,IAAK,GAAL,CAAK,IAAL,CAEL,MAAM,MAEN,WAAW,WAEX,aAAa,aAEb,SAAS,SAET,SAAS,SAET,YAAY,cAZF,QAeL,IAAK,GAAL,CAAK,IAAL,CAEL,QAAQ,QAER,OAAO,OAEP,OAAO,OAEP,OAAO,SARG,QAWL,IAAK,GAAL,CAAK,IAAL,CACL,QAAQ,QACR,UAAU,UACV,SAAS,SACT,YAAY,cAJF,QAOL,IAAK,GAAL,CAAK,IAAL,CAEL,MAAM,MAEN,OAAO,SAJG,QClCL,IAAM,EAAgB,CAE3B,eAAgB,CAAC,EAAG,EAAE,EACtB,oBAAqB,EACrB,cAAe,EAGf,qBAAsB,IACtB,WAAY,IACZ,kBAAmB,EACnB,cAAe,IAGf,iBAAkB,CAAC,EAAE,EACrB,aAAc,EACd,iBAAkB,EAClB,gBAAiB,EAGjB,sBAAuB,GACvB,yBAA0B,IAG1B,gBAAiB,GACjB,aAAc,EACd,aAAc,MAGd,kBAAmB,IACnB,wBAAyB,CACvB,OAAQ,OAAQ,OAAQ,QAAS,OAAQ,OAAQ,OAAQ,OAAQ,MAAO,OAAQ,OAAQ,OAAQ,OAAQ,OACxG,OAAQ,OAAQ,MAClB,CACF,EAKa,EAAuD,OAAO,OAAO,CAC/E,MAAyB,EACzB,KAAwB,IACxB,KAAwB,IACxB,KAAwB,IAC3B,CAAC,EAKY,EAAqD,OAAO,OAAO,CAC7E,MAAyB,KACzB,KAAwB,MACxB,KAAwB,EACxB,KAAwB,IAC3B,CAAC,EAKY,EAAc,CACzB,IAAK,IACL,IAAK,GACP,EAKa,EAAwF,OAAO,OAAO,CAChH,IAAsB,OAAO,OAAO,CAClC,iBACA,gBACA,gBACA,aACH,CAAC,EACA,SAA2B,OAAO,OAAO,CACvC,iBACA,gBACA,gBACA,aACH,CAAC,EACA,OAAyB,OAAO,OAAO,CACrC,mBACA,cACA,cACA,aACH,CAAC,EACA,WAA6B,OAAO,OAAO,CACzC,mBACA,kBACA,kBACA,aACH,CAAC,EACA,OAAyB,OAAO,OAAO,CACrC,eACA,cACA,cACA,aACH,CAAC,EACA,UAA4B,OAAO,OAAO,CACxC,kBACA,iBACA,iBACA,gBACH,CAAC,CACH,CAAC,EAKY,EAA4B,CACvC,WAAY,IACZ,cAAe,GACjB,EAKa,EAAc,CACzB,IAAK,KACL,IAAK,IACP,EAKa,EAAkD,OAAO,OAAO,CAC1E,MAAyB,EACzB,KAAwB,GACxB,KAAwB,GACxB,KAAwB,GAC3B,CAAC,EAKY,EAAqB,GAKrB,EAAkB,CAC7B,SAAU,CACR,KAAM,WACN,YAAa,wCACb,cAAe,CAAC,EAAG,GAAI,IAAI,EAC3B,mBAAoB,EACpB,aAAc,EACd,kBAAmB,GACnB,iBAAkB,IACpB,EACA,QAAS,CACP,KAAM,UACN,YAAa,mCACb,cAAe,CAAC,EAAG,EAAE,EACrB,mBAAoB,EACpB,aAAc,EACd,kBAAmB,GACnB,iBAAkB,GACpB,EACA,UAAW,CACT,KAAM,YACN,YAAa,iDACb,cAAe,CAAC,EAAG,EAAE,EACrB,mBAAoB,EACpB,aAAc,EACd,kBAAmB,GACnB,iBAAkB,IACpB,EACA,MAAO,CACL,KAAM,QACN,YAAa,yCACb,cAAe,CAAC,EAAG,EAAE,EACrB,mBAAoB,EACpB,aAAc,EACd,kBAAmB,GACnB,iBAAkB,GACpB,CACF,EAyBa,EAA0C,OAAO,OAAO,CAClE,IAA0B,OAAO,OAAO,CACvC,gBAAiB,IACjB,gBAAiB,IACjB,qBAAsB,IACxB,CAAC,EACA,KAA2B,OAAO,OAAO,CACxC,eAAgB,EAChB,eAAgB,GAChB,cAAe,IACf,cAAe,MACf,mBAAoB,KACpB,mBAAoB,IACtB,CAAC,CACH,CAAC,EAKY,EAAQ,CAInB,YAAa,CAAC,IAA4B,EAAU,GAAK,KAKzD,SAAU,CAAC,IAAyB,EAAO,GAAK,GAAK,GAAK,KAK1D,UAAW,CAAC,IAA6B,CACvC,IAAM,EAAO,EAAY,IAAM,KAAK,OAAO,GAAK,EAAY,IAAM,EAAY,KAC9E,OAAO,KAAK,IAAI,EAAG,KAAK,MAAM,EAAW,CAAI,CAAC,GAMhD,gBAAiB,CAAC,IAAyB,CACzC,OAAO,KAAK,IAAI,EAAY,IAAK,KAAK,IAAI,EAAM,EAAY,GAAG,CAAC,GAMlE,eAAgB,CAAC,IAAwC,CACvD,GAAI,EAAQ,SAAW,EAAG,MAAO,GACjC,IAAM,EAAc,EAAQ,OAAO,CAAC,EAAK,IAAW,EAAM,EAAc,GAAS,CAAC,EAC5E,EAAc,EAAQ,OAAS,EAAc,QACnD,OAAO,KAAK,MAAO,EAAc,EAAe,GAAG,GAMrD,SAAU,CAAC,IAA8B,GAAY,CACvD",
|
|
9
|
+
"debugId": "38A76FAEB9774D5664756E2164756E21",
|
|
10
|
+
"names": []
|
|
11
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { IBase } from "@ooneex/types";
|
|
2
|
+
interface ILevel extends IBase {
|
|
3
|
+
name: string;
|
|
4
|
+
code: string;
|
|
5
|
+
color: string;
|
|
6
|
+
}
|
|
7
|
+
declare enum ESessionType {
|
|
8
|
+
/** Learning-focused session with detailed explanations and guided experience */
|
|
9
|
+
TRAINING = "training",
|
|
10
|
+
/** Reinforcement session for solidifying already learned knowledge */
|
|
11
|
+
PRACTICE = "practice",
|
|
12
|
+
/** Mock test environment simulating real exam conditions */
|
|
13
|
+
SIMULATION = "simulation",
|
|
14
|
+
/** Quick knowledge check with immediate feedback */
|
|
15
|
+
QUIZ = "quiz",
|
|
16
|
+
/** Competitive or difficult questions designed to test limits */
|
|
17
|
+
CHALLENGE = "challenge",
|
|
18
|
+
/** Multiplayer competitive session with rankings and prizes */
|
|
19
|
+
TOURNAMENT = "tournament",
|
|
20
|
+
/** Session for revisiting previously answered questions and mistakes */
|
|
21
|
+
REVIEW = "review",
|
|
22
|
+
/** Initial assessment to identify knowledge gaps and skill levels */
|
|
23
|
+
DIAGNOSTIC = "diagnostic",
|
|
24
|
+
/** Time-pressured rapid-fire questions focusing on speed and accuracy */
|
|
25
|
+
SPEED_TEST = "speed_test"
|
|
26
|
+
}
|
|
27
|
+
declare enum EAnswerState {
|
|
28
|
+
CORRECT = "correct",
|
|
29
|
+
INCORRECT = "incorrect"
|
|
30
|
+
}
|
|
31
|
+
type SessionTypeItem = {
|
|
32
|
+
readonly code: ESessionType;
|
|
33
|
+
readonly name: string;
|
|
34
|
+
readonly description: string;
|
|
35
|
+
readonly color: string;
|
|
36
|
+
};
|
|
37
|
+
declare const SESSION_TYPES_EN: readonly SessionTypeItem[];
|
|
38
|
+
declare const SESSION_TYPES_FR: readonly SessionTypeItem[];
|
|
39
|
+
declare const SESSION_TYPES_RO: readonly SessionTypeItem[];
|
|
40
|
+
export { SESSION_TYPES_RO, SESSION_TYPES_FR, SESSION_TYPES_EN, ILevel, ESessionType, EAnswerState };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
var n;((e)=>{e.TRAINING="training";e.PRACTICE="practice";e.SIMULATION="simulation";e.QUIZ="quiz";e.CHALLENGE="challenge";e.TOURNAMENT="tournament";e.REVIEW="review";e.DIAGNOSTIC="diagnostic";e.SPEED_TEST="speed_test"})(n||={});var o;((i)=>{i.CORRECT="correct";i.INCORRECT="incorrect"})(o||={});var s=[{code:"training",name:"Training",description:"Learning-focused session with detailed explanations and guided experience. Perfect for acquiring new knowledge and understanding complex concepts step by step.",color:"#3b82f6"},{code:"practice",name:"Practice",description:"Reinforcement session for solidifying already learned knowledge. Helps strengthen understanding through repetition and application of learned concepts.",color:"#10b981"},{code:"simulation",name:"Simulation",description:"Mock test environment simulating real exam conditions. Provides realistic practice experience with authentic timing and pressure conditions.",color:"#f59e0b"},{code:"quiz",name:"Quiz",description:"Quick knowledge check with immediate feedback. Short and focused sessions to assess current understanding and identify areas for improvement.",color:"#8b5cf6"},{code:"challenge",name:"Challenge",description:"Competitive or difficult questions designed to test limits. Advanced sessions that push your knowledge boundaries and critical thinking skills.",color:"#ef4444"},{code:"tournament",name:"Tournament",description:"Multiplayer competitive session with rankings and prizes. Compete against other players in real-time for leaderboard positions and rewards.",color:"#f59e0b"},{code:"review",name:"Review",description:"Session for revisiting previously answered questions and mistakes. Focused practice on areas where improvement is needed based on past performance.",color:"#6b7280"},{code:"diagnostic",name:"Diagnostic",description:"Initial assessment to identify knowledge gaps and skill levels. Comprehensive evaluation to create a personalized learning path.",color:"#06b6d4"},{code:"speed_test",name:"Speed Test",description:"Time-pressured rapid-fire questions focusing on speed and accuracy. Develops quick thinking and decision-making skills under time constraints.",color:"#ec4899"}],t=[{code:"training",name:"Formation",description:"Session d'apprentissage avec explications détaillées et expérience guidée. Parfait pour acquérir de nouvelles connaissances et comprendre des concepts complexes étape par étape.",color:"#3b82f6"},{code:"practice",name:"Pratique",description:"Session de renforcement pour consolider les connaissances déjà apprises. Aide à renforcer la compréhension par la répétition et l'application des concepts appris.",color:"#10b981"},{code:"simulation",name:"Simulation",description:"Environnement d'examen simulé reproduisant les conditions réelles d'examen. Offre une expérience de pratique réaliste avec un timing et une pression authentiques.",color:"#f59e0b"},{code:"quiz",name:"Quiz",description:"Contrôle rapide des connaissances avec feedback immédiat. Sessions courtes et ciblées pour évaluer la compréhension actuelle et identifier les domaines à améliorer.",color:"#8b5cf6"},{code:"challenge",name:"Défi",description:"Questions compétitives ou difficiles conçues pour tester les limites. Sessions avancées qui repoussent vos limites de connaissances et vos compétences de pensée critique.",color:"#ef4444"},{code:"tournament",name:"Tournoi",description:"Session compétitive multijoueur avec classements et prix. Affrontez d'autres joueurs en temps réel pour des positions au classement et des récompenses.",color:"#f59e0b"},{code:"review",name:"Révision",description:"Session pour revoir les questions précédemment répondues et les erreurs. Pratique ciblée sur les domaines nécessitant une amélioration basée sur les performances passées.",color:"#6b7280"},{code:"diagnostic",name:"Diagnostic",description:"Évaluation initiale pour identifier les lacunes de connaissances et les niveaux de compétences. Évaluation complète pour créer un parcours d'apprentissage personnalisé.",color:"#06b6d4"},{code:"speed_test",name:"Test de Vitesse",description:"Questions rapides sous pression temporelle axées sur la vitesse et la précision. Développe la pensée rapide et les compétences de prise de décision sous contraintes de temps.",color:"#ec4899"}],c=[{code:"training",name:"Antrenament",description:"Sesiune de învățare cu explicații detaliate și experiență ghidată. Perfect pentru dobândirea de cunoștințe noi și înțelegerea conceptelor complexe pas cu pas.",color:"#3b82f6"},{code:"practice",name:"Practică",description:"Sesiune de consolidare pentru solidificarea cunoștințelor deja învățate. Ajută la consolidarea înțelegerii prin repetiție și aplicarea conceptelor învățate.",color:"#10b981"},{code:"simulation",name:"Simulare",description:"Mediu de testare simulat care reproduce condițiile reale de examen. Oferă o experiență de practică realistă cu timp și presiune autentice.",color:"#f59e0b"},{code:"quiz",name:"Quiz",description:"Verificare rapidă a cunoștințelor cu feedback imediat. Sesiuni scurte și focalizate pentru a evalua înțelegerea actuală și a identifica domeniile de îmbunătățit.",color:"#8b5cf6"},{code:"challenge",name:"Provocare",description:"Întrebări competitive sau dificile concepute pentru a testa limitele. Sesiuni avansate care îți împing limitele cunoștințelor și abilitățile de gândire critică.",color:"#ef4444"},{code:"tournament",name:"Turneu",description:"Sesiune competitivă multiplayer cu clasamente și premii. Concurează cu alți jucători în timp real pentru poziții în clasament și recompense.",color:"#f59e0b"},{code:"review",name:"Recapitulare",description:"Sesiune pentru revizuirea întrebărilor răspunse anterior și greșelilor. Practică focalizată pe domeniile care necesită îmbunătățire pe baza performanțelor anterioare.",color:"#6b7280"},{code:"diagnostic",name:"Diagnostic",description:"Evaluare inițială pentru identificarea lacunelor de cunoștințe și nivelurilor de competențe. Evaluare cuprinzătoare pentru crearea unei căi de învățare personalizate.",color:"#06b6d4"},{code:"speed_test",name:"Test de Viteză",description:"Întrebări rapide sub presiunea timpului, axate pe viteză și acuratețe. Dezvoltă gândirea rapidă și abilitățile de luare a deciziilor sub constrângeri de timp.",color:"#ec4899"}];export{c as SESSION_TYPES_RO,t as SESSION_TYPES_FR,s as SESSION_TYPES_EN,n as ESessionType,o as EAnswerState};
|
|
2
|
+
|
|
3
|
+
//# debugId=5E9540D7660497F164756E2164756E21
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["src/types.ts", "src/constants.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"import type { IBase } from \"@ooneex/types\";\n\nexport interface ILevel extends IBase {\n name: string;\n code: string;\n color: string;\n}\n\nexport enum ESessionType {\n /** Learning-focused session with detailed explanations and guided experience */\n TRAINING = \"training\",\n /** Reinforcement session for solidifying already learned knowledge */\n PRACTICE = \"practice\",\n /** Mock test environment simulating real exam conditions */\n SIMULATION = \"simulation\",\n /** Quick knowledge check with immediate feedback */\n QUIZ = \"quiz\",\n /** Competitive or difficult questions designed to test limits */\n CHALLENGE = \"challenge\",\n /** Multiplayer competitive session with rankings and prizes */\n TOURNAMENT = \"tournament\",\n /** Session for revisiting previously answered questions and mistakes */\n REVIEW = \"review\",\n /** Initial assessment to identify knowledge gaps and skill levels */\n DIAGNOSTIC = \"diagnostic\",\n /** Time-pressured rapid-fire questions focusing on speed and accuracy */\n SPEED_TEST = \"speed_test\",\n}\n\nexport enum EAnswerState {\n CORRECT = \"correct\",\n INCORRECT = \"incorrect\",\n}\n",
|
|
6
|
+
"import { ESessionType } from \"./types\";\n\ntype SessionTypeItem = {\n readonly code: ESessionType;\n readonly name: string;\n readonly description: string;\n readonly color: string;\n};\n\nexport const SESSION_TYPES_EN: readonly SessionTypeItem[] = [\n {\n code: ESessionType.TRAINING,\n name: \"Training\",\n description:\n \"Learning-focused session with detailed explanations and guided experience. Perfect for acquiring new knowledge and understanding complex concepts step by step.\",\n color: \"#3b82f6\",\n },\n {\n code: ESessionType.PRACTICE,\n name: \"Practice\",\n description:\n \"Reinforcement session for solidifying already learned knowledge. Helps strengthen understanding through repetition and application of learned concepts.\",\n color: \"#10b981\",\n },\n {\n code: ESessionType.SIMULATION,\n name: \"Simulation\",\n description:\n \"Mock test environment simulating real exam conditions. Provides realistic practice experience with authentic timing and pressure conditions.\",\n color: \"#f59e0b\",\n },\n {\n code: ESessionType.QUIZ,\n name: \"Quiz\",\n description:\n \"Quick knowledge check with immediate feedback. Short and focused sessions to assess current understanding and identify areas for improvement.\",\n color: \"#8b5cf6\",\n },\n {\n code: ESessionType.CHALLENGE,\n name: \"Challenge\",\n description:\n \"Competitive or difficult questions designed to test limits. Advanced sessions that push your knowledge boundaries and critical thinking skills.\",\n color: \"#ef4444\",\n },\n {\n code: ESessionType.TOURNAMENT,\n name: \"Tournament\",\n description:\n \"Multiplayer competitive session with rankings and prizes. Compete against other players in real-time for leaderboard positions and rewards.\",\n color: \"#f59e0b\",\n },\n {\n code: ESessionType.REVIEW,\n name: \"Review\",\n description:\n \"Session for revisiting previously answered questions and mistakes. Focused practice on areas where improvement is needed based on past performance.\",\n color: \"#6b7280\",\n },\n {\n code: ESessionType.DIAGNOSTIC,\n name: \"Diagnostic\",\n description:\n \"Initial assessment to identify knowledge gaps and skill levels. Comprehensive evaluation to create a personalized learning path.\",\n color: \"#06b6d4\",\n },\n {\n code: ESessionType.SPEED_TEST,\n name: \"Speed Test\",\n description:\n \"Time-pressured rapid-fire questions focusing on speed and accuracy. Develops quick thinking and decision-making skills under time constraints.\",\n color: \"#ec4899\",\n },\n] as const;\n\nexport const SESSION_TYPES_FR: readonly SessionTypeItem[] = [\n {\n code: ESessionType.TRAINING,\n name: \"Formation\",\n description:\n \"Session d'apprentissage avec explications détaillées et expérience guidée. Parfait pour acquérir de nouvelles connaissances et comprendre des concepts complexes étape par étape.\",\n color: \"#3b82f6\",\n },\n {\n code: ESessionType.PRACTICE,\n name: \"Pratique\",\n description:\n \"Session de renforcement pour consolider les connaissances déjà apprises. Aide à renforcer la compréhension par la répétition et l'application des concepts appris.\",\n color: \"#10b981\",\n },\n {\n code: ESessionType.SIMULATION,\n name: \"Simulation\",\n description:\n \"Environnement d'examen simulé reproduisant les conditions réelles d'examen. Offre une expérience de pratique réaliste avec un timing et une pression authentiques.\",\n color: \"#f59e0b\",\n },\n {\n code: ESessionType.QUIZ,\n name: \"Quiz\",\n description:\n \"Contrôle rapide des connaissances avec feedback immédiat. Sessions courtes et ciblées pour évaluer la compréhension actuelle et identifier les domaines à améliorer.\",\n color: \"#8b5cf6\",\n },\n {\n code: ESessionType.CHALLENGE,\n name: \"Défi\",\n description:\n \"Questions compétitives ou difficiles conçues pour tester les limites. Sessions avancées qui repoussent vos limites de connaissances et vos compétences de pensée critique.\",\n color: \"#ef4444\",\n },\n {\n code: ESessionType.TOURNAMENT,\n name: \"Tournoi\",\n description:\n \"Session compétitive multijoueur avec classements et prix. Affrontez d'autres joueurs en temps réel pour des positions au classement et des récompenses.\",\n color: \"#f59e0b\",\n },\n {\n code: ESessionType.REVIEW,\n name: \"Révision\",\n description:\n \"Session pour revoir les questions précédemment répondues et les erreurs. Pratique ciblée sur les domaines nécessitant une amélioration basée sur les performances passées.\",\n color: \"#6b7280\",\n },\n {\n code: ESessionType.DIAGNOSTIC,\n name: \"Diagnostic\",\n description:\n \"Évaluation initiale pour identifier les lacunes de connaissances et les niveaux de compétences. Évaluation complète pour créer un parcours d'apprentissage personnalisé.\",\n color: \"#06b6d4\",\n },\n {\n code: ESessionType.SPEED_TEST,\n name: \"Test de Vitesse\",\n description:\n \"Questions rapides sous pression temporelle axées sur la vitesse et la précision. Développe la pensée rapide et les compétences de prise de décision sous contraintes de temps.\",\n color: \"#ec4899\",\n },\n] as const;\n\nexport const SESSION_TYPES_RO: readonly SessionTypeItem[] = [\n {\n code: ESessionType.TRAINING,\n name: \"Antrenament\",\n description:\n \"Sesiune de învățare cu explicații detaliate și experiență ghidată. Perfect pentru dobândirea de cunoștințe noi și înțelegerea conceptelor complexe pas cu pas.\",\n color: \"#3b82f6\",\n },\n {\n code: ESessionType.PRACTICE,\n name: \"Practică\",\n description:\n \"Sesiune de consolidare pentru solidificarea cunoștințelor deja învățate. Ajută la consolidarea înțelegerii prin repetiție și aplicarea conceptelor învățate.\",\n color: \"#10b981\",\n },\n {\n code: ESessionType.SIMULATION,\n name: \"Simulare\",\n description:\n \"Mediu de testare simulat care reproduce condițiile reale de examen. Oferă o experiență de practică realistă cu timp și presiune autentice.\",\n color: \"#f59e0b\",\n },\n {\n code: ESessionType.QUIZ,\n name: \"Quiz\",\n description:\n \"Verificare rapidă a cunoștințelor cu feedback imediat. Sesiuni scurte și focalizate pentru a evalua înțelegerea actuală și a identifica domeniile de îmbunătățit.\",\n color: \"#8b5cf6\",\n },\n {\n code: ESessionType.CHALLENGE,\n name: \"Provocare\",\n description:\n \"Întrebări competitive sau dificile concepute pentru a testa limitele. Sesiuni avansate care îți împing limitele cunoștințelor și abilitățile de gândire critică.\",\n color: \"#ef4444\",\n },\n {\n code: ESessionType.TOURNAMENT,\n name: \"Turneu\",\n description:\n \"Sesiune competitivă multiplayer cu clasamente și premii. Concurează cu alți jucători în timp real pentru poziții în clasament și recompense.\",\n color: \"#f59e0b\",\n },\n {\n code: ESessionType.REVIEW,\n name: \"Recapitulare\",\n description:\n \"Sesiune pentru revizuirea întrebărilor răspunse anterior și greșelilor. Practică focalizată pe domeniile care necesită îmbunătățire pe baza performanțelor anterioare.\",\n color: \"#6b7280\",\n },\n {\n code: ESessionType.DIAGNOSTIC,\n name: \"Diagnostic\",\n description:\n \"Evaluare inițială pentru identificarea lacunelor de cunoștințe și nivelurilor de competențe. Evaluare cuprinzătoare pentru crearea unei căi de învățare personalizate.\",\n color: \"#06b6d4\",\n },\n {\n code: ESessionType.SPEED_TEST,\n name: \"Test de Viteză\",\n description:\n \"Întrebări rapide sub presiunea timpului, axate pe viteză și acuratețe. Dezvoltă gândirea rapidă și abilitățile de luare a deciziilor sub constrângeri de timp.\",\n color: \"#ec4899\",\n },\n] as const;\n"
|
|
7
|
+
],
|
|
8
|
+
"mappings": "AAQO,IAAK,GAAL,CAAK,IAAL,CAEL,WAAW,WAEX,WAAW,WAEX,aAAa,aAEb,OAAO,OAEP,YAAY,YAEZ,aAAa,aAEb,SAAS,SAET,aAAa,aAEb,aAAa,eAlBH,QAqBL,IAAK,GAAL,CAAK,IAAL,CACL,UAAU,UACV,YAAY,cAFF,QCpBL,IAAM,EAA+C,CAC1D,CACE,gBACA,KAAM,WACN,YACE,kKACF,MAAO,SACT,EACA,CACE,gBACA,KAAM,WACN,YACE,0JACF,MAAO,SACT,EACA,CACE,kBACA,KAAM,aACN,YACE,+IACF,MAAO,SACT,EACA,CACE,YACA,KAAM,OACN,YACE,gJACF,MAAO,SACT,EACA,CACE,iBACA,KAAM,YACN,YACE,kJACF,MAAO,SACT,EACA,CACE,kBACA,KAAM,aACN,YACE,8IACF,MAAO,SACT,EACA,CACE,cACA,KAAM,SACN,YACE,sJACF,MAAO,SACT,EACA,CACE,kBACA,KAAM,aACN,YACE,mIACF,MAAO,SACT,EACA,CACE,kBACA,KAAM,aACN,YACE,iJACF,MAAO,SACT,CACF,EAEa,EAA+C,CAC1D,CACE,gBACA,KAAM,YACN,YACE,oLACF,MAAO,SACT,EACA,CACE,gBACA,KAAM,WACN,YACE,qKACF,MAAO,SACT,EACA,CACE,kBACA,KAAM,aACN,YACE,qKACF,MAAO,SACT,EACA,CACE,YACA,KAAM,OACN,YACE,uKACF,MAAO,SACT,EACA,CACE,iBACA,KAAM,OACN,YACE,6KACF,MAAO,SACT,EACA,CACE,kBACA,KAAM,UACN,YACE,0JACF,MAAO,SACT,EACA,CACE,cACA,KAAM,WACN,YACE,6KACF,MAAO,SACT,EACA,CACE,kBACA,KAAM,aACN,YACE,2KACF,MAAO,SACT,EACA,CACE,kBACA,KAAM,kBACN,YACE,iLACF,MAAO,SACT,CACF,EAEa,EAA+C,CAC1D,CACE,gBACA,KAAM,cACN,YACE,iKACF,MAAO,SACT,EACA,CACE,gBACA,KAAM,WACN,YACE,+JACF,MAAO,SACT,EACA,CACE,kBACA,KAAM,WACN,YACE,6IACF,MAAO,SACT,EACA,CACE,YACA,KAAM,OACN,YACE,oKACF,MAAO,SACT,EACA,CACE,iBACA,KAAM,YACN,YACE,mKACF,MAAO,SACT,EACA,CACE,kBACA,KAAM,SACN,YACE,+IACF,MAAO,SACT,EACA,CACE,cACA,KAAM,eACN,YACE,yKACF,MAAO,SACT,EACA,CACE,kBACA,KAAM,aACN,YACE,yKACF,MAAO,SACT,EACA,CACE,kBACA,KAAM,iBACN,YACE,iKACF,MAAO,SACT,CACF",
|
|
9
|
+
"debugId": "5E9540D7660497F164756E2164756E21",
|
|
10
|
+
"names": []
|
|
11
|
+
}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { IImage } from "@ooneex/image";
|
|
2
|
+
import { IStatus } from "@ooneex/status";
|
|
3
|
+
import { ITag } from "@ooneex/tag";
|
|
4
|
+
import { IBase as IBase2, IStat } from "@ooneex/types";
|
|
5
|
+
import { IBase } from "@ooneex/types";
|
|
6
|
+
interface ILevel extends IBase {
|
|
7
|
+
name: string;
|
|
8
|
+
code: string;
|
|
9
|
+
color: string;
|
|
10
|
+
}
|
|
11
|
+
declare enum ESessionType {
|
|
12
|
+
/** Learning-focused session with detailed explanations and guided experience */
|
|
13
|
+
TRAINING = "training",
|
|
14
|
+
/** Reinforcement session for solidifying already learned knowledge */
|
|
15
|
+
PRACTICE = "practice",
|
|
16
|
+
/** Mock test environment simulating real exam conditions */
|
|
17
|
+
SIMULATION = "simulation",
|
|
18
|
+
/** Quick knowledge check with immediate feedback */
|
|
19
|
+
QUIZ = "quiz",
|
|
20
|
+
/** Competitive or difficult questions designed to test limits */
|
|
21
|
+
CHALLENGE = "challenge",
|
|
22
|
+
/** Multiplayer competitive session with rankings and prizes */
|
|
23
|
+
TOURNAMENT = "tournament",
|
|
24
|
+
/** Session for revisiting previously answered questions and mistakes */
|
|
25
|
+
REVIEW = "review",
|
|
26
|
+
/** Initial assessment to identify knowledge gaps and skill levels */
|
|
27
|
+
DIAGNOSTIC = "diagnostic",
|
|
28
|
+
/** Time-pressured rapid-fire questions focusing on speed and accuracy */
|
|
29
|
+
SPEED_TEST = "speed_test"
|
|
30
|
+
}
|
|
31
|
+
declare enum EAnswerState {
|
|
32
|
+
CORRECT = "correct",
|
|
33
|
+
INCORRECT = "incorrect"
|
|
34
|
+
}
|
|
35
|
+
declare enum EMcqQuestionChoiceLetter {
|
|
36
|
+
A = "A",
|
|
37
|
+
B = "B",
|
|
38
|
+
C = "C",
|
|
39
|
+
D = "D",
|
|
40
|
+
E = "E",
|
|
41
|
+
F = "F",
|
|
42
|
+
G = "G",
|
|
43
|
+
H = "H",
|
|
44
|
+
I = "I",
|
|
45
|
+
J = "J"
|
|
46
|
+
}
|
|
47
|
+
declare enum EMcqSessionStatus {
|
|
48
|
+
DRAFT = "draft",
|
|
49
|
+
STARTED = "started",
|
|
50
|
+
PAUSED = "paused",
|
|
51
|
+
COMPLETED = "completed"
|
|
52
|
+
}
|
|
53
|
+
interface IMcqQuestionChoice extends IBase2 {
|
|
54
|
+
letter: EMcqQuestionChoiceLetter;
|
|
55
|
+
text: string;
|
|
56
|
+
isCorrect: boolean;
|
|
57
|
+
explanation?: string;
|
|
58
|
+
question: IMcqQuestion;
|
|
59
|
+
}
|
|
60
|
+
interface IMcqQuestion extends IBase2 {
|
|
61
|
+
questionNumber: number;
|
|
62
|
+
text: string;
|
|
63
|
+
choices: IMcqQuestionChoice[];
|
|
64
|
+
context?: string;
|
|
65
|
+
contextId?: string;
|
|
66
|
+
stat?: IStat;
|
|
67
|
+
status?: IStatus;
|
|
68
|
+
image?: IImage;
|
|
69
|
+
tags?: ITag[];
|
|
70
|
+
}
|
|
71
|
+
interface IMcqSession extends IBase2 {
|
|
72
|
+
name: string;
|
|
73
|
+
totalQuestions: number;
|
|
74
|
+
answeredCount: number;
|
|
75
|
+
correctCount: number;
|
|
76
|
+
incorrectCount: number;
|
|
77
|
+
timing: number;
|
|
78
|
+
questions: IMcqQuestion[];
|
|
79
|
+
status: EMcqSessionStatus;
|
|
80
|
+
score: number;
|
|
81
|
+
startedAt?: Date | null;
|
|
82
|
+
pausedAt?: Date | null;
|
|
83
|
+
resumedAt?: Date | null;
|
|
84
|
+
completedAt?: Date | null;
|
|
85
|
+
type: ESessionType;
|
|
86
|
+
level: ILevel;
|
|
87
|
+
}
|
|
88
|
+
interface IMcqSessionQuestion extends IBase2 {
|
|
89
|
+
session: IMcqSession;
|
|
90
|
+
question: IMcqQuestion;
|
|
91
|
+
questionNumber: number;
|
|
92
|
+
selectedChoices: IMcqQuestionChoice[];
|
|
93
|
+
context?: string;
|
|
94
|
+
contextId?: string;
|
|
95
|
+
state: EAnswerState;
|
|
96
|
+
score: number;
|
|
97
|
+
}
|
|
98
|
+
export { IMcqSessionQuestion, IMcqSession, IMcqQuestionChoice, IMcqQuestion, EMcqSessionStatus, EMcqQuestionChoiceLetter };
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
var n;((e)=>{e.A="A";e.B="B";e.C="C";e.D="D";e.E="E";e.F="F";e.G="G";e.H="H";e.I="I";e.J="J"})(n||={});var s;((t)=>{t.DRAFT="draft";t.STARTED="started";t.PAUSED="paused";t.COMPLETED="completed"})(s||={});export{s as EMcqSessionStatus,n as EMcqQuestionChoiceLetter};
|
|
2
|
+
|
|
3
|
+
//# debugId=EA8EAD6A5D8BC75D64756E2164756E21
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["src/mcq/types.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"import type { IImage } from \"@ooneex/image\";\nimport type { IStatus } from \"@ooneex/status\";\nimport type { ITag } from \"@ooneex/tag\";\nimport type { IBase, IStat } from \"@ooneex/types\";\nimport type { EAnswerState, ESessionType, ILevel } from \"@/types\";\n\nexport enum EMcqQuestionChoiceLetter {\n A = \"A\",\n B = \"B\",\n C = \"C\",\n D = \"D\",\n E = \"E\",\n F = \"F\",\n G = \"G\",\n H = \"H\",\n I = \"I\",\n J = \"J\",\n}\n\nexport enum EMcqSessionStatus {\n DRAFT = \"draft\",\n STARTED = \"started\",\n PAUSED = \"paused\",\n COMPLETED = \"completed\",\n}\n\nexport interface IMcqQuestionChoice extends IBase {\n letter: EMcqQuestionChoiceLetter;\n text: string;\n isCorrect: boolean;\n explanation?: string;\n question: IMcqQuestion;\n}\n\nexport interface IMcqQuestion extends IBase {\n questionNumber: number;\n text: string;\n choices: IMcqQuestionChoice[];\n context?: string;\n contextId?: string;\n stat?: IStat;\n status?: IStatus;\n image?: IImage;\n tags?: ITag[];\n}\n\nexport interface IMcqSession extends IBase {\n name: string;\n totalQuestions: number;\n answeredCount: number;\n correctCount: number;\n incorrectCount: number;\n timing: number;\n questions: IMcqQuestion[];\n status: EMcqSessionStatus;\n score: number;\n startedAt?: Date | null;\n pausedAt?: Date | null;\n resumedAt?: Date | null;\n completedAt?: Date | null;\n type: ESessionType;\n level: ILevel;\n}\n\nexport interface IMcqSessionQuestion extends IBase {\n session: IMcqSession;\n question: IMcqQuestion;\n questionNumber: number;\n selectedChoices: IMcqQuestionChoice[];\n context?: string;\n contextId?: string;\n state: EAnswerState;\n score: number;\n}\n"
|
|
6
|
+
],
|
|
7
|
+
"mappings": "AAMO,IAAK,GAAL,CAAK,IAAL,CACL,IAAI,IACJ,IAAI,IACJ,IAAI,IACJ,IAAI,IACJ,IAAI,IACJ,IAAI,IACJ,IAAI,IACJ,IAAI,IACJ,IAAI,IACJ,IAAI,MAVM,QAaL,IAAK,GAAL,CAAK,IAAL,CACL,QAAQ,QACR,UAAU,UACV,SAAS,SACT,YAAY,cAJF",
|
|
8
|
+
"debugId": "EA8EAD6A5D8BC75D64756E2164756E21",
|
|
9
|
+
"names": []
|
|
10
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@ooneex/gamification",
|
|
3
|
+
"description": "",
|
|
4
|
+
"version": "0.0.1",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"files": [
|
|
7
|
+
"dist",
|
|
8
|
+
"LICENSE",
|
|
9
|
+
"README.md",
|
|
10
|
+
"package.json"
|
|
11
|
+
],
|
|
12
|
+
"module": "./dist/index.js",
|
|
13
|
+
"types": "./dist/index.d.ts",
|
|
14
|
+
"exports": {
|
|
15
|
+
".": {
|
|
16
|
+
"import": {
|
|
17
|
+
"types": "./dist/index.d.ts",
|
|
18
|
+
"default": "./dist/index.js"
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
"./mcq": {
|
|
22
|
+
"import": {
|
|
23
|
+
"types": "./dist/mcq/index.d.ts",
|
|
24
|
+
"default": "./dist/mcq/index.js"
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
"./flashcard": {
|
|
28
|
+
"import": {
|
|
29
|
+
"types": "./dist/flashcard/index.d.ts",
|
|
30
|
+
"default": "./dist/flashcard/index.js"
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
"./package.json": "./package.json"
|
|
34
|
+
},
|
|
35
|
+
"license": "MIT",
|
|
36
|
+
"scripts": {
|
|
37
|
+
"build": "bunup",
|
|
38
|
+
"lint": "tsgo --noEmit && bunx biome lint",
|
|
39
|
+
"publish:prod": "bun publish --tolerate-republish --access public",
|
|
40
|
+
"publish:pack": "bun pm pack --destination ./dist",
|
|
41
|
+
"publish:dry": "bun publish --dry-run"
|
|
42
|
+
},
|
|
43
|
+
"dependencies": {},
|
|
44
|
+
"devDependencies": {
|
|
45
|
+
"@ooneex/image": "0.0.1",
|
|
46
|
+
"@ooneex/status": "0.0.1",
|
|
47
|
+
"@ooneex/tag": "0.0.1",
|
|
48
|
+
"@ooneex/types": "0.0.1"
|
|
49
|
+
},
|
|
50
|
+
"peerDependencies": {}
|
|
51
|
+
}
|