feat: Puente Mayúscula-Minúscula + TTS SpeechSynthesis + E2E fixes

This commit is contained in:
renato97
2026-07-21 15:31:46 -03:00
commit fa8e0c58ce
120 changed files with 16013 additions and 0 deletions
+50
View File
@@ -0,0 +1,50 @@
import { fsrs as createFSRS, createEmptyCard, Rating, type Card, type Grade } from "ts-fsrs"
const scheduler = createFSRS({ maximum_interval: 365, request_retention: 0.9 })
export type FsrsGrade = "again" | "hard" | "good" | "easy"
const gradeMap: Record<FsrsGrade, Grade> = {
again: Rating.Again,
hard: Rating.Hard,
good: Rating.Good,
easy: Rating.Easy,
}
export function buildFsrsCard(params: {
stability?: number
difficulty?: number
reps?: number
lapses?: number
due?: Date
}): Card {
const card = createEmptyCard(params.due ?? new Date())
return {
...card,
stability: params.stability ?? card.stability,
difficulty: params.difficulty ?? card.difficulty,
reps: params.reps ?? 0,
lapses: params.lapses ?? 0,
due: params.due ?? card.due,
}
}
export function gradeCard(card: Card, grade: FsrsGrade, now: Date = new Date()) {
const result = scheduler.next(card, now, gradeMap[grade])
return {
card: result.card,
log: result.log,
}
}
export function getRetrievability(card: Card, now: Date = new Date()): number {
const r = scheduler.get_retrievability(card, now, false)
return typeof r === "number" ? r : parseFloat(r)
}
export function skillCodeFromGrade(correct: boolean, responseMs: number): FsrsGrade {
if (!correct) return "again"
if (responseMs > 8000) return "hard"
if (responseMs > 4000) return "good"
return "easy"
}