455 lines
17 KiB
YAML
455 lines
17 KiB
YAML
# Main menu
|
|
menu:
|
|
subtitle: 'Terminal Typing Tutor'
|
|
adaptive_drill: 'Adaptive Drill'
|
|
adaptive_drill_desc: 'Phonetic words with adaptive letter unlocking'
|
|
code_drill: 'Code Drill'
|
|
code_drill_desc: 'Practice typing code syntax'
|
|
passage_drill: 'Passage Drill'
|
|
passage_drill_desc: 'Type passages from books'
|
|
skill_tree: 'Skill Tree'
|
|
skill_tree_desc: 'View progression branches and launch drills'
|
|
keyboard: 'Keyboard'
|
|
keyboard_desc: 'Explore keyboard layout and key statistics'
|
|
statistics: 'Statistics'
|
|
statistics_desc: 'View your typing statistics'
|
|
settings: 'Settings'
|
|
settings_desc: 'Configure keydr'
|
|
day_streak: ' | %{days} day streak'
|
|
key_progress: ' Key Progress %{unlocked}/%{total} (%{mastered} mastered) | Target %{target} WPM%{streak}'
|
|
hint_start: '[1-3] Start'
|
|
hint_skill_tree: '[t] Skill Tree'
|
|
hint_keyboard: '[b] Keyboard'
|
|
hint_stats: '[s] Stats'
|
|
hint_settings: '[c] Settings'
|
|
hint_quit: '[q] Quit'
|
|
|
|
# Drill screen
|
|
drill:
|
|
title: ' Drill '
|
|
mode_adaptive: 'Adaptive'
|
|
mode_code: 'Code (Unranked)'
|
|
mode_passage: 'Passage (Unranked)'
|
|
focus_char: 'Focus: ''%{ch}'''
|
|
focus_bigram: 'Focus: "%{bigram}"'
|
|
focus_both: 'Focus: ''%{ch}'' + "%{bigram}"'
|
|
header_wpm: 'WPM'
|
|
header_acc: 'Acc'
|
|
header_err: 'Err'
|
|
code_source: ' Code source '
|
|
passage_source: ' Passage source '
|
|
footer: '[ESC] End drill [Backspace] Delete'
|
|
keys_reenabled: 'Keys re-enabled in %{ms}ms'
|
|
hint_end: '[ESC] End drill'
|
|
hint_backspace: '[Backspace] Delete'
|
|
|
|
# Dashboard / drill result
|
|
dashboard:
|
|
title: ' Drill Complete '
|
|
results: 'Results'
|
|
unranked_note_prefix: ' (Unranked'
|
|
unranked_note_suffix: ' does not count toward skill tree)'
|
|
speed: ' Speed: '
|
|
accuracy_label: ' Accuracy: '
|
|
time_label: ' Time: '
|
|
errors_label: ' Errors: '
|
|
correct_detail: ' (%{correct}/%{total} correct)'
|
|
input_blocked: ' Input temporarily blocked '
|
|
input_blocked_ms: '(%{ms}ms remaining)'
|
|
hint_continue: '[c/Enter/Space] Continue'
|
|
hint_retry: '[r] Retry'
|
|
hint_menu: '[q] Menu'
|
|
hint_stats: '[s] Stats'
|
|
hint_delete: '[x] Delete'
|
|
|
|
# Stats sidebar (during drill)
|
|
sidebar:
|
|
title: ' Stats '
|
|
wpm: 'WPM: '
|
|
target: 'Target: '
|
|
target_wpm: '%{wpm} WPM'
|
|
accuracy: 'Accuracy: '
|
|
progress: 'Progress: '
|
|
correct: 'Correct: '
|
|
errors: 'Errors: '
|
|
time: 'Time: '
|
|
last_drill: ' Last Drill '
|
|
vs_avg: ' vs avg: '
|
|
|
|
# Statistics dashboard
|
|
stats:
|
|
title: ' Statistics '
|
|
empty: 'No drills completed yet. Start typing!'
|
|
tab_dashboard: '[1] Dashboard'
|
|
tab_history: '[2] History'
|
|
tab_activity: '[3] Activity'
|
|
tab_accuracy: '[4] Accuracy'
|
|
tab_timing: '[5] Timing'
|
|
tab_ngrams: '[6] N-grams'
|
|
hint_back: '[ESC] Back'
|
|
hint_next_tab: '[Tab] Next tab'
|
|
hint_switch_tab: '[1-6] Switch tab'
|
|
hint_navigate: '[j/k] Navigate'
|
|
hint_page: '[PgUp/PgDn] Page'
|
|
hint_delete: '[x] Delete'
|
|
summary_title: ' Summary '
|
|
drills: ' Drills: '
|
|
avg_wpm: ' Avg WPM: '
|
|
best_wpm: ' Best WPM: '
|
|
accuracy_label: ' Accuracy: '
|
|
total_time: ' Total time: '
|
|
wpm_chart_title: ' WPM per Drill (Last 20, Target: %{target}) '
|
|
accuracy_chart_title: ' Accuracy %% (Last 50 Drills) '
|
|
chart_drill: 'Drill #'
|
|
chart_accuracy_pct: 'Accuracy %%'
|
|
sessions_title: ' Recent Sessions '
|
|
session_header: ' # WPM Raw Acc%% Time Date/Time Mode Ranked Partial'
|
|
session_separator: ' ─────────────────────────────────────────────────────────────────────'
|
|
delete_confirm: 'Delete session #%{idx}? (y/n)'
|
|
confirm_title: ' Confirm '
|
|
yes: 'yes'
|
|
no: 'no'
|
|
keyboard_accuracy_title: ' Keyboard Accuracy %% '
|
|
keyboard_timing_title: ' Keyboard Timing (ms) '
|
|
slowest_keys_title: ' Slowest Keys (ms) '
|
|
fastest_keys_title: ' Fastest Keys (ms) '
|
|
worst_accuracy_title: ' Worst Accuracy (%%) '
|
|
best_accuracy_title: ' Best Accuracy (%%) '
|
|
not_enough_data: ' Not enough data'
|
|
streaks_title: ' Streaks '
|
|
current_streak: ' Current: '
|
|
best_streak: ' Best: '
|
|
active_days: ' Active Days: '
|
|
top_days_none: ' Top Days: none'
|
|
top_days: ' Top Days: %{days}'
|
|
wpm_label: ' WPM: %{avg}/%{target} (%{pct}%%)'
|
|
acc_label: ' Acc: %{pct}%%'
|
|
keys_label: ' Keys: %{unlocked}/%{total} (%{mastered} mastered)'
|
|
ngram_empty: 'Complete some adaptive drills to see n-gram data'
|
|
ngram_header_speed_narrow: ' Bgrm Speed Expct Anom%'
|
|
ngram_header_error_narrow: ' Bgrm Err Smp Rate Exp Anom%'
|
|
ngram_header_speed: ' Bigram Speed Expect Samples Anom%'
|
|
ngram_header_error: ' Bigram Errors Samples Rate Expect Anom%'
|
|
focus_title: ' Active Focus '
|
|
focus_char_label: ' Focus: '
|
|
focus_bigram_value: 'Bigram %{label}'
|
|
focus_plus: ' + '
|
|
anomaly_error: 'error'
|
|
anomaly_speed: 'speed'
|
|
focus_detail_both: ' Char ''%{ch}'': weakest key | Bigram %{label}: %{type} anomaly %{pct}%%'
|
|
focus_detail_char_only: ' Char ''%{ch}'': weakest key, no confirmed bigram anomalies'
|
|
focus_detail_bigram_only: ' (%{type} anomaly: %{pct}%%)'
|
|
focus_empty: ' Complete some adaptive drills to see focus data'
|
|
error_anomalies_title: ' Error Anomalies (%{count}) '
|
|
no_error_anomalies: ' No error anomalies detected'
|
|
speed_anomalies_title: ' Speed Anomalies (%{count}) '
|
|
no_speed_anomalies: ' No speed anomalies detected'
|
|
scope_label_prefix: ' '
|
|
bi_label: ' | Bi: %{count}'
|
|
hes_label: ' | Hes: >%{ms}ms'
|
|
focus_char_value: 'Char ''%{ch}'''
|
|
|
|
# Activity heatmap
|
|
heatmap:
|
|
title: ' Daily Activity (Sessions per Day) '
|
|
jan: 'Jan'
|
|
feb: 'Feb'
|
|
mar: 'Mar'
|
|
apr: 'Apr'
|
|
may: 'May'
|
|
jun: 'Jun'
|
|
jul: 'Jul'
|
|
aug: 'Aug'
|
|
sep: 'Sep'
|
|
oct: 'Oct'
|
|
nov: 'Nov'
|
|
dec: 'Dec'
|
|
|
|
# Chart
|
|
chart:
|
|
wpm_over_time: ' WPM Over Time '
|
|
drill_number: 'Drill #'
|
|
|
|
# Settings
|
|
settings:
|
|
title: ' Settings '
|
|
subtitle: 'Use arrows to navigate, Enter/Right to change, ESC to save & exit'
|
|
target_wpm: 'Target WPM'
|
|
theme: 'Theme'
|
|
word_count: 'Word Count'
|
|
ui_language: 'UI Language'
|
|
dictionary_language: 'Dictionary Language'
|
|
keyboard_layout: 'Keyboard Layout'
|
|
code_language: 'Code Language'
|
|
code_downloads: 'Code Downloads'
|
|
on: 'On'
|
|
off: 'Off'
|
|
code_download_dir: 'Code Download Dir'
|
|
snippets_per_repo: 'Snippets per Repo'
|
|
unlimited: 'Unlimited'
|
|
download_code_now: 'Download Code Now'
|
|
run_downloader: 'Run downloader'
|
|
passage_downloads: 'Passage Downloads'
|
|
passage_download_dir: 'Passage Download Dir'
|
|
paragraphs_per_book: 'Paragraphs per Book'
|
|
whole_book: 'Whole book'
|
|
download_passages_now: 'Download Passages Now'
|
|
export_path: 'Export Path'
|
|
export_data: 'Export Data'
|
|
export_now: 'Export now'
|
|
import_path: 'Import Path'
|
|
import_data: 'Import Data'
|
|
import_now: 'Import now'
|
|
hint_save_back: '[ESC] Save & back'
|
|
hint_change_value: '[Enter/arrows] Change value'
|
|
hint_edit_path: '[Enter on path] Edit'
|
|
hint_move: '[←→] Move'
|
|
hint_tab_complete: '[Tab] Complete (at end)'
|
|
hint_confirm: '[Enter] Confirm'
|
|
hint_cancel: '[Esc] Cancel'
|
|
success_title: ' Success '
|
|
error_title: ' Error '
|
|
press_any_key: 'Press any key'
|
|
file_exists_title: ' File Exists '
|
|
file_exists: 'A file already exists at this path.'
|
|
overwrite_rename: '[d] Overwrite [r] Rename [Esc] Cancel'
|
|
erase_warning: 'This will erase your current data.'
|
|
export_first: 'Export first if you want to keep it.'
|
|
proceed_yn: 'Proceed? (y/n)'
|
|
confirm_import_title: ' Confirm Import '
|
|
|
|
# Selection screens
|
|
select:
|
|
dictionary_language_title: ' Select Dictionary Language '
|
|
keyboard_layout_title: ' Select Keyboard Layout '
|
|
code_language_title: ' Select Code Language '
|
|
passage_source_title: ' Select Passage Source '
|
|
ui_language_title: ' Select UI Language '
|
|
more_above: '... %{count} more above ...'
|
|
more_below: '... %{count} more below ...'
|
|
current: ' (current)'
|
|
disabled: ' (disabled)'
|
|
enabled_default: ' (enabled, default: %{layout})'
|
|
enabled: ' (enabled)'
|
|
disabled_blocked: ' (disabled: blocked)'
|
|
built_in: ' (built-in)'
|
|
cached: ' (cached)'
|
|
disabled_download: ' (disabled: download required)'
|
|
download_required: ' (download required)'
|
|
hint_navigate: '[Up/Down/PgUp/PgDn] Navigate'
|
|
hint_confirm: '[Enter] Confirm'
|
|
hint_back: '[ESC] Back'
|
|
language_resets_layout: 'Selecting a language resets keyboard layout to that language''s default.'
|
|
layout_no_language_change: 'Layout changes do not change dictionary language.'
|
|
disabled_network_notice: 'Some languages are disabled: enable network downloads in intro/settings.'
|
|
disabled_sources_notice: 'Some sources are disabled: enable network downloads in intro/settings.'
|
|
passage_all: 'All (Built-in + all books)'
|
|
passage_builtin: 'Built-in passages only'
|
|
passage_book_prefix: 'Book: %{title}'
|
|
|
|
# Progress
|
|
progress:
|
|
overall_key_progress: 'Overall Key Progress'
|
|
unlocked_mastered: '%{unlocked}/%{total} unlocked (%{mastered} mastered)'
|
|
|
|
# Skill tree
|
|
skill_tree:
|
|
title: ' Skill Tree '
|
|
locked: 'Locked'
|
|
unlocked: 'unlocked'
|
|
mastered: 'mastered'
|
|
in_progress: 'in progress'
|
|
complete: 'complete'
|
|
locked_status: 'locked'
|
|
locked_notice: 'Complete %{count} primary letters to unlock branches'
|
|
branches_separator: 'Branches (available after %{count} primary letters)'
|
|
unlocked_letters: 'Unlocked %{unlocked}/%{total} letters'
|
|
level: 'Level %{current}/%{total}'
|
|
level_zero: 'Level 0/%{total}'
|
|
in_focus: ' in focus'
|
|
hint_navigate: '[↑↓/jk] Navigate'
|
|
hint_scroll: '[PgUp/PgDn or Ctrl+U/Ctrl+D] Scroll'
|
|
hint_back: '[q] Back'
|
|
hint_unlock: '[Enter] Unlock'
|
|
hint_start_drill: '[Enter] Start Drill'
|
|
unlock_msg_1: 'Once unlocked, the default adaptive drill will mix in keys in this branch that are unlocked.'
|
|
unlock_msg_2: 'If you want to focus only on this branch, launch a drill directly from this branch in the Skill Tree.'
|
|
confirm_unlock: 'Unlock %{branch}?'
|
|
confirm_yn: '[y] Unlock [n/ESC] Cancel'
|
|
lvl_prefix: 'Lvl'
|
|
branch_primary_letters: 'Primary Letters'
|
|
branch_capital_letters: 'Capital Letters'
|
|
branch_numbers: 'Numbers 0-9'
|
|
branch_prose_punctuation: 'Prose Punctuation'
|
|
branch_whitespace: 'Whitespace'
|
|
branch_code_symbols: 'Code Symbols'
|
|
level_frequency_order: 'Frequency Order'
|
|
level_common_sentence_capitals: 'Common Sentence Capitals'
|
|
level_name_capitals: 'Name Capitals'
|
|
level_remaining_capitals: 'Remaining Capitals'
|
|
level_common_digits: 'Common Digits'
|
|
level_all_digits: 'All Digits'
|
|
level_essential: 'Essential'
|
|
level_common: 'Common'
|
|
level_expressive: 'Expressive'
|
|
level_enter_return: 'Enter/Return'
|
|
level_tab_indent: 'Tab/Indent'
|
|
level_arithmetic_assignment: 'Arithmetic & Assignment'
|
|
level_grouping: 'Grouping'
|
|
level_logic_reference: 'Logic & Reference'
|
|
level_special: 'Special'
|
|
|
|
# Milestones
|
|
milestones:
|
|
unlock_title: ' Key Unlocked! '
|
|
mastery_title: ' Key Mastered! '
|
|
branches_title: ' New Skill Branches Available! '
|
|
branch_complete_title: ' Branch Complete! '
|
|
all_unlocked_title: ' Every Key Unlocked! '
|
|
all_mastered_title: ' Full Keyboard Mastery! '
|
|
unlocked: 'unlocked'
|
|
mastered: 'mastered'
|
|
use_finger: 'Use your %{finger} finger'
|
|
hold_right_shift: 'Hold Right Shift (right pinky)'
|
|
hold_left_shift: 'Hold Left Shift (left pinky)'
|
|
congratulations_all_letters: 'Congratulations! You''ve mastered all %{count} primary letters'
|
|
new_branches_available: 'New skill branches are now available:'
|
|
visit_skill_tree: 'Visit the Skill Tree to unlock a new branch'
|
|
and_start_training: 'and start training!'
|
|
open_skill_tree: 'Press [t] to open the Skill Tree now'
|
|
branch_complete_msg: 'You''ve completed the %{branch} branch!'
|
|
all_levels_mastered: 'All %{count} levels mastered.'
|
|
all_keys_confident: 'Every key in this branch is at full confidence.'
|
|
all_unlocked_msg: 'You''ve unlocked every key on the keyboard!'
|
|
all_unlocked_desc: 'Every character, symbol, and modifier is now available in your drills.'
|
|
keep_practicing_mastery: 'Keep practicing to build mastery — once every key reaches full'
|
|
confidence_complete: 'confidence, you''ll have achieved complete keyboard mastery!'
|
|
all_mastered_msg: 'Congratulations — you''ve reached full keyboard mastery!'
|
|
all_mastered_desc: 'Every key on the keyboard is at maximum confidence.'
|
|
mastery_takes_practice: 'Mastery is not a destination — it takes ongoing practice.'
|
|
keep_drilling: 'Keep drilling to maintain your edge.'
|
|
hint_skill_tree_continue: '[t] Open Skill Tree [Any other key] Continue'
|
|
hint_any_key: 'Press any key to continue'
|
|
input_blocked: 'Input temporarily blocked (%{ms}ms remaining)'
|
|
unlock_msg_1: 'Nice work! Keep building your typing skills.'
|
|
unlock_msg_2: 'Another key added to your arsenal!'
|
|
unlock_msg_3: 'Your keyboard is growing! Keep it up.'
|
|
unlock_msg_4: 'One step closer to full keyboard mastery!'
|
|
mastery_msg_1: 'This key is now at full confidence!'
|
|
mastery_msg_2: 'You''ve got this key down pat!'
|
|
mastery_msg_3: 'Muscle memory locked in!'
|
|
mastery_msg_4: 'One more key conquered!'
|
|
|
|
# Keyboard explorer
|
|
keyboard:
|
|
title: ' Keyboard '
|
|
subtitle: 'Press any key or click a key'
|
|
hint_navigate: '[←→↑↓/hjkl/Tab] Navigate'
|
|
hint_back: '[q/ESC] Back'
|
|
key_label: 'Key: '
|
|
finger_label: 'Finger: '
|
|
hand_left: 'Left'
|
|
hand_right: 'Right'
|
|
finger_index: 'Index'
|
|
finger_middle: 'Middle'
|
|
finger_ring: 'Ring'
|
|
finger_pinky: 'Pinky'
|
|
finger_thumb: 'Thumb'
|
|
overall_accuracy: ' Overall accuracy: %{correct}/%{total} (%{pct}%%)'
|
|
ranked_accuracy: ' Ranked accuracy: %{correct}/%{total} (%{pct}%%)'
|
|
confidence: 'Confidence: '
|
|
no_data: 'No data yet'
|
|
no_data_short: 'No data'
|
|
key_details: ' Key Details '
|
|
key_details_char: ' Key Details: ''%{ch}'' '
|
|
key_details_name: ' Key Details: %{name} '
|
|
press_key_hint: 'Press a key to see its details'
|
|
shift_label: 'Shift: '
|
|
shift_no: 'No'
|
|
overall_avg_time: 'Overall Avg Time: '
|
|
overall_best_time: 'Overall Best Time: '
|
|
overall_samples: 'Overall Samples: '
|
|
overall_accuracy_label: 'Overall Accuracy: '
|
|
branch_label: 'Branch: '
|
|
level_label: 'Level: '
|
|
built_in_key: 'Built-in Key'
|
|
unlocked_label: 'Unlocked: '
|
|
yes: 'Yes'
|
|
no: 'No'
|
|
in_focus_label: 'In Focus?: '
|
|
mastery_label: 'Mastery: '
|
|
mastery_locked: 'Locked'
|
|
ranked_avg_time: 'Ranked Avg Time: '
|
|
ranked_best_time: 'Ranked Best Time: '
|
|
ranked_samples: 'Ranked Samples: '
|
|
ranked_accuracy_label: 'Ranked Accuracy: '
|
|
|
|
# Intro dialogs
|
|
intro:
|
|
passage_title: ' Passage Downloads Setup '
|
|
code_title: ' Code Downloads Setup '
|
|
enable_downloads: 'Enable network downloads'
|
|
download_dir: 'Download directory'
|
|
paragraphs_per_book: 'Paragraphs per book (0 = whole)'
|
|
whole_book: 'whole book'
|
|
snippets_per_repo: 'Snippets per repo (0 = unlimited)'
|
|
unlimited: 'unlimited'
|
|
start_passage_drill: 'Start passage drill'
|
|
start_code_drill: 'Start code drill'
|
|
confirm: 'Confirm'
|
|
hint_navigate: '[Up/Down] Navigate'
|
|
hint_adjust: '[Left/Right] Adjust'
|
|
hint_edit: '[Type/Backspace] Edit'
|
|
hint_confirm: '[Enter] Confirm'
|
|
hint_cancel: '[ESC] Cancel'
|
|
preparing_download: 'Preparing download...'
|
|
download_passage_title: ' Downloading Passage Source '
|
|
download_code_title: ' Downloading Code Source '
|
|
book_label: ' Book: %{name}'
|
|
repo_label: ' Repo: %{name}'
|
|
progress_bytes: '[%{name}] %{downloaded}/%{total} bytes'
|
|
downloaded_bytes: 'Downloaded: %{bytes} bytes'
|
|
downloading_book_progress: 'Downloading current book: [%{bar}] %{downloaded}/%{total} bytes'
|
|
downloading_book_bytes: 'Downloading current book: %{bytes} bytes'
|
|
downloading_code_progress: 'Downloading: [%{bar}] %{downloaded}/%{total} bytes'
|
|
downloading_code_bytes: 'Downloading: %{bytes} bytes'
|
|
current_book: 'Current: %{name} (book %{done}/%{total})'
|
|
current_repo: 'Current: %{name} (repo %{done}/%{total})'
|
|
passage_instructions_1: 'keydr can download passages from Project Gutenberg for typing practice.'
|
|
passage_instructions_2: 'Books are downloaded once and cached locally.'
|
|
passage_instructions_3: 'Configure download settings below, then start a passage drill.'
|
|
code_instructions_1: 'keydr can download open-source code from GitHub for typing practice.'
|
|
code_instructions_2: 'Code is downloaded once and cached locally.'
|
|
code_instructions_3: 'Configure download settings below, then start a code drill.'
|
|
|
|
# Status messages (from app.rs)
|
|
status:
|
|
recovery_files: 'Recovery files found from interrupted import. Data may be inconsistent — consider re-importing.'
|
|
dir_not_exist: 'Directory does not exist: %{path}'
|
|
no_data_store: 'No data store available'
|
|
serialization_error: 'Serialization error: %{error}'
|
|
exported_to: 'Exported to %{path}'
|
|
export_failed: 'Export failed: %{error}'
|
|
could_not_read: 'Could not read file: %{error}'
|
|
invalid_export: 'Invalid export file: %{error}'
|
|
unsupported_version: 'Unsupported export version: %{got} (expected %{expected})'
|
|
import_failed: 'Import failed: %{error}'
|
|
imported_theme_fallback: 'Imported successfully (theme ''%{theme}'' not found, using default)'
|
|
imported_success: 'Imported successfully'
|
|
adaptive_unavailable: 'Adaptive ranked mode unavailable: %{error}'
|
|
switched_to: 'Switched to %{name}'
|
|
layout_changed: 'Layout changed to %{name}'
|
|
|
|
# Errors (for UI boundary translation)
|
|
errors:
|
|
unknown_language: 'Unknown language: %{key}'
|
|
unknown_layout: 'Unknown keyboard layout: %{key}'
|
|
unsupported_pair: 'Unsupported language/layout pair: %{language} + %{layout}'
|
|
language_blocked: 'Language is blocked by support level: %{key}'
|
|
|
|
# Common
|
|
common:
|
|
wpm: 'WPM'
|
|
cpm: 'CPM'
|
|
back: 'Back'
|