Áleran Vocals
Piano, entrenamiento con micrófono y juegos de oído para alumnos de canto: notas, escalas, afinación, rango vocal, resistencia e intervalos.
翻译准备中
尚未检测到更新。GitHub 发布版本后会显示在这里。
个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证制作者的介绍仅有上面的一句话。 更多详情请阅读仓库 README。 仓库 README ↗
正在加载完整 README。
查看完整 README ↗An endless, timed hiragana reading game. Read real Japanese words and random kana combos, type the romaji, beat the clock. Built to grow into a full Japanese learning platform.
Next.js 16 (App Router) + TypeScript + Tailwind CSS v4 + shadcn-style components + Lucide icons. No database, API key or account needed. Progress lives in localStorage.
Needs Node 20.9+ (22 recommended).
npm install
npm run dev # http://localhost:3000
Other scripts:
npm test # vitest unit tests (quiz generation, grading, filtering, progress)
npm run typecheck # tsc --noEmit
npm run lint # eslint
npm run build # production build
npm start # serve the production build
git init, commit, push).main redeploys automatically. No environment variables needed.CLI alternative: npm i -g vercel && vercel from the project folder.
Optional. With no Supabase keys the site runs guest-only, exactly as before. Setup steps: SETUP-ACCOUNTS.md.
/login, /signup, /forgot-password, /reset-password, plus /auth/callback and /auth/confirm for email and Google links./profile: avatar, username, stats, password change, sign out (this device or everywhere), data download.localStorage keys. After signing in, users are asked once whether to add it to their account (a backup is kept).kana-dojo:v1:u:<id>:...) that syncs to one user_progress row. Saves happen locally first, then upload about 1.5 s later. It works offline and catches up when back online.rev number, and a stale save is rejected, merged and retried (src/lib/sync/).supabase/migrations/. Row Level Security limits every user to their own rows. supabase/tests/ has the SQL tests used to check it./leaderboard: weekly board of correct answers, for signed in users. 0002_leaderboard.sql adds a weekly_leaderboard() function that reads each user's synced day log and returns only name, belt and score, so progress stays private. Users can hide themselves in Settings.Where things live:
| Path | What |
|---|---|
src/lib/supabase/ | client setup, public key guard, safe redirects |
src/lib/sync/ | merge rules, sync engine, Supabase storage adapter (all unit tested) |
src/features/auth/ | auth provider (session + sync), login/signup/password forms |
src/features/profile/ | profile page |
src/store/app-store.ts | per-user local storage, guest import |
src/lib/quiz/timer.ts from its length, lookalike characters (ぬ/め, ね/れ/わ...), characters you're weak on, characters you've never seen, and whether it's a nonsense combo. The pace setting scales it (Relaxed ×1.6, Normal, Fast ×0.7), and Zen turns timers off. The clock pauses when the tab is hidden.| Key | Action |
|---|---|
| Enter | Lock in / next answer. Enter on the last one grades the round |
| Shift+Enter | Skip round (when shortcuts are on) |
| Enter or N | Next round after grading (when shortcuts are on) |
src/
app/ routes only, thin wrappers
layout.tsx fonts, no-flash theme script, app shell
page.tsx dashboard
practice/ chart/ progress/ settings/
globals.css design tokens (light + dark) and animations
components/
ui/ shadcn-style primitives (button, card, dialog, switch, misc)
layout/ app shell (sidebar + mobile tab bar), theme sync, page header
features/ one folder per product area
dashboard/
hiragana/practice/ the game: practice-game, question-card, round-summary, petals
hiragana/chart/ interactive chart + character detail dialog
progress/ stats page, svg charts, session list
settings/
lib/ pure logic, no React, fully unit-tested
kana/ character data (types.ts, hiragana.ts)
vocab/ word lists (hiragana-words.ts)
quiz/ generate.ts, validate.ts, grade.ts, timer.ts, adaptive.ts, session.ts
game/ scoring.ts (points, combos, stars, xp)
progress/ types, update.ts (fold a round in), stats.ts (derived numbers), sanitize.ts
settings/ types, defaults, sanitize
storage/ local.ts, the Repository interface over localStorage
modules.ts nav + "coming soon" module registry
sound.ts webaudio sound effects
store/app-store.ts single external store (useSyncExternalStore), all actions
| Feature | Where |
|---|---|
| Dakuten / handakuten / small kana | Add a new KanaSet next to HIRAGANA_BASIC_SET in lib/kana/hiragana.ts. Small kana combos (きゃ) need splitKana to group digraphs. Words go in lib/vocab/. Then widen resolveEnabled in lib/quiz/generate.ts, which is the single gate that enforces the v1 basic-46 rule. |
| Katakana | lib/kana/katakana.ts with the same KanaChar shape (script: "katakana"), a vocab file, and a features/katakana/ folder reusing the practice components. Flip it to live in lib/modules.ts. |
| Kanji / JLPT vocab | Extend VocabWord in lib/vocab/types.ts (it already has an optional jlpt field), add data files, and a new feature folder. |
| Spaced repetition / flashcards | Per-item stats already exist (CharStat, WordStat in lib/progress/types.ts). Add due dates there and a scheduler in lib/quiz/. Weighting lives in lib/quiz/adaptive.ts. |
| Audio / listening | Add audioUrl to VocabWord; play it from question-card.tsx. |
| Accounts + cloud sync | Implement the Repository<T> interface from lib/storage/local.ts against your API (Supabase, a Next.js route handler, etc.) and swap it in store/app-store.ts. Nothing else talks to storage. |
| AI lessons | A route handler under app/api/ plus a feature folder. The quiz engine takes any VocabWord[] via GenerateInput.vocab. |
| Timer tuning | lib/quiz/timer.ts (BASE_SEC, PER_KANA_SEC, PACE_MULT). |
| Scoring / levels | lib/game/scoring.ts and levelInfo in lib/progress/stats.ts. |
Stored data is versioned under the kana-dojo:v1: prefix and every read goes through a sanitizer, so corrupted or old data falls back to safe defaults instead of crashing. Bump the prefix if you ever change the shape incompatibly.
src/**/*.test.ts covers:
localStorage data