bisaja fixes
All checks were successful
Deploy to production / deploy (push) Successful in 2m4s

This commit is contained in:
Torsten Schulz (local)
2026-06-19 15:04:12 +02:00
parent 39c5a36d70
commit 15ab450ca9
2 changed files with 193 additions and 0 deletions

View File

@@ -16,6 +16,87 @@ import { Op } from 'sequelize';
import { BISAYA_PHASE1_DIDACTICS, BISAYA_DIDACTICS_FRAGMENTS } from '../scripts/bisaya-course-phase1.js';
export default class VocabService {
_stripGermanNumberSeparators(value) {
return String(value || '').replace(/[\s.-]+/g, '');
}
_germanNumberParts() {
return new Map([
['null', 0],
['ein', 1], ['eins', 1], ['eine', 1], ['einen', 1], ['einem', 1], ['einer', 1],
['zwei', 2], ['drei', 3], ['vier', 4],
['fuenf', 5], ['funf', 5], ['fünf', 5],
['sechs', 6], ['sieben', 7], ['acht', 8], ['neun', 9],
['zehn', 10], ['elf', 11],
['zwoelf', 12], ['zwolf', 12], ['zwölf', 12],
['dreizehn', 13], ['vierzehn', 14],
['fuenfzehn', 15], ['funfzehn', 15], ['fünfzehn', 15],
['sechzehn', 16], ['siebzehn', 17], ['achtzehn', 18], ['neunzehn', 19],
['zwanzig', 20], ['dreissig', 30], ['dreißig', 30], ['vierzig', 40],
['fuenfzig', 50], ['funfzig', 50], ['fünfzig', 50],
['sechzig', 60], ['siebzig', 70], ['achtzig', 80], ['neunzig', 90]
]);
}
_parseGermanUnderHundred(compact) {
const parts = this._germanNumberParts();
if (!compact) return null;
if (parts.has(compact)) {
return parts.get(compact);
}
const undIndex = compact.indexOf('und');
if (undIndex > 0) {
const onesPart = compact.slice(0, undIndex);
const tensPart = compact.slice(undIndex + 3);
const ones = parts.get(onesPart);
const tens = parts.get(tensPart);
if (ones >= 1 && ones <= 9 && tens >= 20 && tens % 10 === 0) {
return tens + ones;
}
}
return null;
}
_canonicalizeGermanNumberAnswer(value) {
const compact = this._stripGermanNumberSeparators(String(value || '').trim().toLowerCase());
if (!compact) return '';
if (/^\d+$/.test(compact)) {
return String(Number(compact));
}
const parts = this._germanNumberParts();
if (parts.has(compact)) {
return String(parts.get(compact));
}
const tausendIndex = compact.indexOf('tausend');
if (tausendIndex !== -1) {
const thousandsPart = compact.slice(0, tausendIndex);
const remainderPart = compact.slice(tausendIndex + 'tausend'.length);
const thousands = thousandsPart ? this._canonicalizeGermanNumberAnswer(thousandsPart) : '1';
const remainder = remainderPart ? this._canonicalizeGermanNumberAnswer(remainderPart) : '0';
if (thousands && remainder) {
return String((Number(thousands) * 1000) + Number(remainder));
}
}
const hundertIndex = compact.indexOf('hundert');
if (hundertIndex !== -1) {
const hundredsPart = compact.slice(0, hundertIndex);
const remainderPart = compact.slice(hundertIndex + 'hundert'.length);
const hundreds = hundredsPart ? this._canonicalizeGermanNumberAnswer(hundredsPart) : '1';
const remainder = remainderPart ? this._parseGermanUnderHundred(remainderPart) : 0;
if (hundreds && remainder !== null) {
return String((Number(hundreds) * 100) + Number(remainder));
}
}
const underHundred = this._parseGermanUnderHundred(compact);
return underHundred === null ? '' : String(underHundred);
}
_normalizeSrsText(value) {
return String(value || '')
.trim()
@@ -727,6 +808,10 @@ export default class VocabService {
}
_normalizeTextAnswer(text) {
const canonicalNumber = this._canonicalizeGermanNumberAnswer(text);
if (canonicalNumber) {
return canonicalNumber;
}
const normalized = String(text || '')
.trim()
.toLowerCase()
@@ -734,6 +819,10 @@ export default class VocabService {
.replace(/[\p{P}\p{S}]+/gu, ' ')
.replace(/\s+/g, ' ')
.trim();
const normalizedCanonicalNumber = this._canonicalizeGermanNumberAnswer(normalized);
if (normalizedCanonicalNumber) {
return normalizedCanonicalNumber;
}
return normalized.replace(/\s+/g, '');
}