data: switch to recovered game DB and refresh cards and charts
Publish GitHub Pages output / publish (push) Successful in 44s

This commit is contained in:
2026-09-29 22:48:08 +09:00
parent 5783072b12
commit 07b98db520
1259 changed files with 11228 additions and 6809 deletions
+21 -1
View File
@@ -171,5 +171,25 @@ export function parseSusTimeline(text) {
throw new Error(`${headers.get('MUSIC_ID')}: SUS category mismatch: regular ${regularCount}/${expectedRegular}, mid ${midCount}/${expectedMid}, flick ${flickCount}/${headers.get('FLICK_NOTE_COUNT')}`);
}
notes.sort((left, right) => left.timeSeconds - right.timeSeconds || (left.type === 'mid' ? 1 : -1));
return { songId: headers.get('MUSIC_ID'), notes, specialStartSeconds: specialStarts.sort((left, right) => left - right).map(secondsAt) };
// Keep visual geometry separate from score judgements (invisible continuation ticks
// are not tap notes, and a hold-end flick still has regular score weight).
const directional = new Map(flicks.filter(note => [1, 3, 4].includes(note.kind)).map(note => [key(note), note.kind === 3 ? 'left' : note.kind === 4 ? 'right' : 'up']));
const criticals = new Set(taps.filter(note => [2, 6].includes(note.kind)).map(key));
const attached = new Set(taps.filter(note => note.kind === 3).map(key));
const point = note => ({ timeSeconds: secondsAt(note.beat), lane: note.lane - 2, width: note.width });
const visualNote = (note, kind) => ({ ...point(note), kind,
...(directional.has(key(note)) ? { direction: directional.get(key(note)) } : {}),
...(criticals.has(key(note)) ? { critical: true } : {}) });
const visualNotes = taps.filter(note => [1, 2].includes(note.kind) && !holdStartKeys.has(key(note)) && !holdEndKeys.has(key(note)))
.map(note => visualNote(note, directional.has(key(note)) ? 'flick' : 'tap'));
visualNotes.push(...flicks.filter(note => [1, 3, 4].includes(note.kind) && !tapKeys.has(key(note)) && !holdStartKeys.has(key(note)) && !holdEndKeys.has(key(note)))
.map(note => visualNote(note, 'flick')));
for (const hold of holds) {
visualNotes.push(visualNote(hold[0], 'hold'), visualNote(hold.at(-1), 'hold'));
}
visualNotes.push(...visibleRelays.map(note => visualNote(note, 'relay')));
const visualHolds = holds.map(hold => hold.filter((note, i) => i === 0 || i === hold.length - 1 || !attached.has(key(note)))
.map(note => ({ ...point(note), ...(note.kind === 4 ? { control: true } : {}) })));
return { songId: headers.get('MUSIC_ID'), notes, specialStartSeconds: specialStarts.sort((left, right) => left - right).map(secondsAt),
visual: { laneCount: 12, notes: visualNotes.sort((a, b) => a.timeSeconds - b.timeSeconds), holds: visualHolds } };
}